Exemple #1
0
// GenerateRevocation creates a Revocation that revokes the given member
// private key.
func (priv *PrivateKey) GenerateRevocation(mem *MemberKey) *Revocation {
	s := new(big.Int).Add(priv.gamma, mem.x)
	s.ModInverse(s, bn256.Order)
	aStar := new(bn256.G2).ScalarMult(priv.g2, s)

	return &Revocation{mem.x, mem.a, aStar}
}
Exemple #2
0
// Decrypt takes two integers, resulting from an ElGamal encryption, and
// returns the plaintext of the message. An error can result only if the
// ciphertext is invalid. Users should keep in mind that this is a padding
// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
// be used to break the cryptosystem.  See ``Chosen Ciphertext Attacks
// Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel
// Bleichenbacher, Advances in Cryptology (Crypto '98),
func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
	s := new(big.Int).Exp(c1, priv.X, priv.P)
	s.ModInverse(s, priv.P)
	s.Mul(s, c2)
	s.Mod(s, priv.P)
	em := s.Bytes()

	firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)

	// The remainder of the plaintext must be a string of non-zero random
	// octets, followed by a 0, followed by the message.
	//   lookingForIndex: 1 iff we are still looking for the zero.
	//   index: the offset of the first zero byte.
	var lookingForIndex, index int
	lookingForIndex = 1

	for i := 1; i < len(em); i++ {
		equals0 := subtle.ConstantTimeByteEq(em[i], 0)
		index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
		lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
	}

	if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
		return nil, errors.New("elgamal: decryption error")
	}
	return em[index+1:], nil
}
//newPrivateKey makes private key from seeds.
func newPrivateKey(pSeed, qSeed big.Int) (*PrivateKey, error) {
	q := &qSeed
	p := &pSeed
	var tmp big.Int
	test := big.NewInt(0x7743)
	var q1, phi, keyD, keyN big.Int
	for count := 0; count < rsaCreateGiveup; count++ {
		q = primize(q)
		q1.Add(q, tmp.SetInt64(-1))
		p = primize(p)
		phi.Add(p, tmp.SetInt64(-1))
		phi.Mul(&phi, &q1)
		keyD.ModInverse(rsaPublicE, &phi)
		if keyD.Cmp(tmp.SetInt64(0)) == 0 {
			continue
		}
		keyN.Mul(p, q)
		tmp.Exp(test, rsaPublicE, &keyN)
		tmp.Exp(&tmp, &keyD, &keyN)
		if tmp.Cmp(test) == 0 {
			return &PrivateKey{&keyN, &keyD}, nil
		}
		p.Add(p, tmp.SetInt64(2))
		q.Add(q, tmp.SetInt64(2))
	}
	err := errors.New("cannot generate private key")
	log.Fatal(err)
	return nil, err
}
Exemple #4
0
func (d *ecdsa) Sign(m []byte) (*big.Int, *big.Int) {
	h := sha1.New()
	if n, err := h.Write(m); n != len(m) || err != nil {
		log.Fatal("Error calculating hash")
	}
	e := h.Sum(nil)
	r, s := new(big.Int), new(big.Int)
	n := d.g.Size()
	z := new(big.Int).SetBytes(e)
	z.Mod(z, n)
	for r.Cmp(new(big.Int)) == 0 || s.Cmp(new(big.Int)) == 0 {
		k := new(big.Int).Rand(rnd, n)
		if k.Cmp(new(big.Int)) == 0 {
			continue
		}
		p := d.g.Pow(d.g.Generator(), k)
		r.Mod(p.(*ellipticCurveElement).x, n)

		k.ModInverse(k, n)
		s.Mul(r, d.key)
		s.Add(s, z)
		s.Mul(s, k)
		s.Mod(s, n)
	}
	return r, s
}
Exemple #5
0
func computeX1(p, g, h, x1 *big.Int) *big.Int {
	t1 := new(big.Int).Exp(g, x1, p)
	t2 := t1.ModInverse(t1, p)
	t3 := t2.Mul(t2, h)
	t3.Mod(t3, p)

	return t3
}
Exemple #6
0
func main() {
	raw, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		log.Fatalln(err)
	}

	raw_strings := strings.Fields(strings.Replace(string(raw), "\n", " ", -1))

	p, _ := new(big.Int).SetString(raw_strings[0], 0)
	g, _ := new(big.Int).SetString(raw_strings[1], 0)
	h, _ := new(big.Int).SetString(raw_strings[2], 0)

	B := big.NewInt(2)
	B.Exp(B, big.NewInt(20), p)
	mitms := make(map[string]*big.Int)
	one := big.NewInt(1)

	fmt.Println("p:", p)
	fmt.Println("g:", g)
	fmt.Println("h:", h)

	fmt.Println("Started calculating")

	for i := big.NewInt(0); i.Cmp(B) != 0; i.Add(i, one) {
		ex := new(big.Int).Exp(g, i, p)
		ex.ModInverse(ex, p)

		res := ex.Mul(ex, h)
		res.Mod(res, p)

		mitms[res.String()] = new(big.Int).Set(i)
	}

	fmt.Println("Calculated x1s")

	var x1, x0 *big.Int
	var ok bool
	for i := big.NewInt(0); i.Cmp(B) != 0; i.Add(i, one) {
		r := new(big.Int).Exp(g, B, p)
		r.Exp(r, i, p)

		if x1, ok = mitms[r.String()]; ok {
			x0 = new(big.Int).Set(i)
			fmt.Println("Found x0", x0, "x1", x1)
			break
		}
	}

	if x1 == nil || x0 == nil {
		fmt.Println("Something went wrong - no solution")
	} else {
		x := x0.Mul(x0, B)
		x.Add(x, x1)

		fmt.Println(x)
	}
}
Exemple #7
0
// Set to a * b^-1 mod M, where b^-1 is the modular inverse of b.
func (i *Int) Div(a, b abstract.Secret) abstract.Secret {
	ai := a.(*Int)
	bi := b.(*Int)
	var t big.Int
	i.M = ai.M
	i.V.Mul(&ai.V, t.ModInverse(&bi.V, i.M))
	i.V.Mod(&i.V, i.M)
	return i
}
Exemple #8
0
// returns (P / Q, P % Q)
func (p Poly) Div(q Poly, m *big.Int) (quo, rem Poly) {
	if m != nil {
		p.sanitize(m)
		q.sanitize(m)
	}
	if p.GetDegree() < q.GetDegree() || q.isZero() {
		quo = NewPolyInts(0)
		rem = p.Clone(0)
		return
	}
	quo = make([]*big.Int, p.GetDegree()-q.GetDegree()+1)
	rem = p.Clone(0)
	for i := 0; i < len(quo); i++ {
		quo[i] = big.NewInt(0)
	}
	t := p.Clone(0)
	qd := q.GetDegree()
	for {
		td := t.GetDegree()
		rd := td - qd
		if rd < 0 || t.isZero() {
			rem = t
			break
		}
		r := new(big.Int)
		if m != nil {
			r.ModInverse(q[qd], m)
			r.Mul(r, t[td])
			r.Mod(r, m)
		} else {
			r.Div(t[td], q[qd])
		}
		// if r == 0, it means that the highest coefficient of the result is not an integer
		// this polynomial library handles integer coefficients
		if r.Cmp(big.NewInt(0)) == 0 {
			quo = NewPolyInts(0)
			rem = p.Clone(0)
			return
		}
		u := q.Clone(rd)
		for i := rd; i < len(u); i++ {
			u[i].Mul(u[i], r)
			if m != nil {
				u[i].Mod(u[i], m)
			}
		}
		t = t.Sub(u, m)
		t.trim()
		quo[rd] = r
	}
	quo.trim()
	rem.trim()
	return
}
Exemple #9
0
func main() {
	pi := new(big.Int)
	pi.SetString("7199773997391911030609999317773941274322764333428698921736339643928346453700085358802973900485592910475480089726140708102474957429903531369589969318716771", 10)
	gi := new(big.Int)
	gi.SetString("4565356397095740655436854503483826832136106141639563487732438195343690437606117828318042418238184896212352329118608100083187535033402010599512641674644143", 10)
	q := new(big.Int)
	q.SetString("236234353446506858198510045061214171961", 10)

	G := dh.NewFiniteGroup(*pi)
	g := dh.NewFiniteElement(G, *gi)
	GG := dh.NewGeneratedGroup(G, g, *q)
	d := dh.NewDiffieHellman(GG)

	factors := dh.FindCoFactors(q, pi, G)

	moduli := make(map[int64]int64)
	total := big.NewInt(1)

	for factor, h := range factors {
		total.Mul(total, big.NewInt(factor))
		mac := Bob(d, h)
		log.Printf("Guessing the shared secret in the subgroup of order %d", factor)
		found := false
		for i := int64(1); i <= factor; i++ {
			k := G.Pow(h, big.NewInt(i))
			if hmac.Equal(mac, Sign(secretMessage, k)) {
				//log.Printf("%d^%d", elt, i)
				found = true
				moduli[factor] = i
				break
			}
		}
		if !found {
			panic("Could not guess the shared secret")
		}
	}

	// From Wikipedia CRT page
	x := new(big.Int)
	for n, a := range moduli {
		N := new(big.Int).Set(total)
		N.Div(N, big.NewInt(n))
		N.ModInverse(N, big.NewInt(n))
		N.Mul(N, total)
		N.Div(N, big.NewInt(n))
		N.Mul(N, big.NewInt(a))
		x.Add(x, N)
		x.Mod(x, total)
	}
	log.Printf("Predicted key: %d", x)

	log.Printf("%s", d)
}
Exemple #10
0
// Returns (N, e, d) of the given size that encrypts decBytes to encBytes
func chosenEncrytion(decBytes, encBytes []byte, keySize int) (N, e, d *big.Int) {
	padM := new(big.Int).SetBytes(encBytes)
	sig := new(big.Int).SetBytes(decBytes)
	eveP, evePFactors := choosePrime(keySize/2, padM, sig, nil)
	eveQ, eveQFactors := choosePrime(keySize/2, padM, sig, evePFactors)
	eveN := new(big.Int).Mul(eveP, eveQ)

	ep := pohlig(padM, sig, eveP, evePFactors)

	eq := pohlig(padM, sig, eveQ, eveQFactors)

	evePhi := new(big.Int).Set(eveN)
	evePhi.Sub(evePhi, eveP)
	evePhi.Sub(evePhi, eveQ)
	evePhi.Add(evePhi, big.NewInt(1))

	// From Wikipedia CRT page
	eveModuli := make(map[*big.Int]*big.Int)
	newP := new(big.Int).Sub(eveP, big.NewInt(1))
	newQ := new(big.Int).Sub(eveQ, big.NewInt(1))
	// Remove "2" factor so CRT works.
	newP.Div(newP, big.NewInt(2))
	newQ.Div(newQ, big.NewInt(2))
	eveModuli[newP] = new(big.Int).Mod(ep, newP)
	eveModuli[newQ] = new(big.Int).Mod(eq, newQ)
	if new(big.Int).Mod(eq, big.NewInt(2)).Cmp(new(big.Int).Mod(ep, big.NewInt(2))) != 0 {
		log.Fatal("ep and eq are not compatible and CRT won't work")
	}
	eveModuli[big.NewInt(4)] = new(big.Int).Mod(eq, big.NewInt(4))
	eveE := new(big.Int)
	for n, a := range eveModuli {
		N := new(big.Int).Set(evePhi)
		scratch := new(big.Int)
		scratch.Mod(N, n)
		if scratch.Cmp(new(big.Int)) != 0 {
			log.Fatalf("hmm %d / %d", N, n)
		}
		N.Div(N, n)
		scratch.GCD(nil, nil, N, n)
		if scratch.Cmp(big.NewInt(1)) != 0 {
			log.Fatalf("GCD: %d", scratch)
		}
		N.ModInverse(N, n)
		N.Mul(N, evePhi)
		N.Div(N, n)
		N.Mul(N, a)
		eveE.Add(eveE, N)
		eveE.Mod(eveE, evePhi)
	}

	return eveN, eveE, new(big.Int).ModInverse(eveE, evePhi)
}
Exemple #11
0
/* R = 2P */
func (R *Point) double(P *Point, C *Curve) *Point {
	//If at infinity
	if P.inf {
		R.SetInf()
	} else {
		//Calculate slope
		//s = (3*Px² + a) / (2*Py) mod p
		t1 := new(big.Int).Exp(P.x, big.NewInt(2), C.p) // t1 = Px² mod p

		s := new(big.Int).Mul(t1, big.NewInt(3)) // s = 3 * t1

		s.Mod(s, C.p) // s = s mod p

		s.Add(s, C.a) // s = s + a mod p
		s.Mod(s, C.p)

		sd := new(big.Int).Mul(big.NewInt(2), P.y)

		sd.ModInverse(sd, C.p) // sd = 1 / 2*Py mod p

		s.Mul(s, sd) // s = (s / sd) mod p
		s.Mod(s, C.p)

		//Calculate Rx
		//Rx = s² - 2*Px mod p
		s2 := new(big.Int).Exp(s, big.NewInt(2), C.p) //s2 = s²
		s2.Mod(s2, C.p)

		t := new(big.Int).Mul(P.x, big.NewInt(2)) // t = 2*Px mod p
		t.Mod(t, C.p)

		t.Sub(s2, t) // Rx = s2 - t mod p
		R.x.Mod(t, C.p)

		//Calculate Ry using algorithm shown to the right of the commands
		//Ry = s(Px-Rx) - Py mod p

		t.Sub(P.x, R.x) //t = Px - Rx mod p
		t.Mod(t, C.p)

		t.Mul(s, t) //t = s * t mod p
		t.Mod(t, C.p)

		t.Sub(t, P.y) //t = t - Py mod p
		R.y.Mod(t, C.p)

		// 		mpz_mod(R->y, t3, curve->p);	//Ry = t3 mod p

	}
	return R
}
Exemple #12
0
func q1() {
	n := new(big.Int)
	sqrtN := new(big.Int)
	a := new(big.Int)
	asquared := new(big.Int)
	one := new(big.Int)
	x := new(big.Int)
	xsquared := new(big.Int)
	//p := new(big.Int)

	n.SetString("179769313486231590772930519078902473361797697894230657273430081157732675805505620686985379449212982959585501387537164015710139858647833778606925583497541085196591615128057575940752635007475935288710823649949940771895617054361149474865046711015101563940680527540071584560878577663743040086340742855278549092581", 10)
	one.SetString("1", 10)

	sqrtN = mathutil.SqrtBig(n)
	a.Add(sqrtN, one)
	asquared.Mul(a, a)

	xsquared.Sub(asquared, n)

	x = mathutil.SqrtBig(xsquared)

	p := new(big.Int)
	q := new(big.Int)
	p.Sub(a, x)
	q.Add(a, x)

	fmt.Println(a.Sub(a, x).String())

	d := new(big.Int)
	phiN := new(big.Int)
	phiN.Mul(p.Sub(p, one), q.Sub(q, one))
	e := new(big.Int)
	e.SetString("65537", 10)

	//get my decryption exponent
	d.ModInverse(e, phiN)

	c := new(big.Int)
	c.SetString("22096451867410381776306561134883418017410069787892831071731839143676135600120538004282329650473509424343946219751512256465839967942889460764542040581564748988013734864120452325229320176487916666402997509188729971690526083222067771600019329260870009579993724077458967773697817571267229951148662959627934791540", 10)

	m := new(big.Int)
	m.Exp(c, d, n)

	fmt.Println("decrypted message:")
	fmt.Printf("%x\n", m.Bytes())

	//020805907610b524330594e51d5dbbf643f09603731e9817111392d0c64e2739959a092d4daf979d387520ea7e577af9eb50a29f736925e810ab2fb4640e091a0f73252cb669d5b62b26764190ed188239fe71e1a7cb9e935d2db55c98b024e1dae46d00
	answer, _ := hex.DecodeString("466163746f72696e67206c65747320757320627265616b205253412e")
	fmt.Printf("%s\n", answer)
}
Exemple #13
0
// Calculates the Modular Inverse of a given Prime number such that
// (PRIME * MODULAR_INVERSE) & (MAX_INT_VALUE) = 1
// Panics if n is not a valid prime number.
// See: http://en.wikipedia.org/wiki/Modular_multiplicative_inverse
func ModInverse(n uint64) uint64 {

	p := big.NewInt(int64(n))
	if !p.ProbablyPrime(MILLER_RABIN) {
		accuracy := 1.0 - 1.0/math.Pow(float64(4), float64(MILLER_RABIN))
		panic(jsonerror.New(2, "Number is not prime", fmt.Sprintf("n=%d. %d Miller-Rabin tests done. Accuracy: %f", n, MILLER_RABIN, accuracy)))
	}

	var i big.Int

	prime := big.NewInt(int64(n))
	max := big.NewInt(int64(MAX_INT + 1))

	return i.ModInverse(prime, max).Uint64()
}
Exemple #14
0
func TestModInv(t *testing.T) {
	A := new(big.Int)
	B := new(big.Int)
	for _, a := range numbers {
		if a == 0 {
			continue
		}
		A.SetUint64(a)
		b := mod_inv(a)
		B.ModInverse(A, P)
		expected := B.Uint64()
		if b != expected {
			t.Fatalf("inv(%d): Expecting %d but got %d", a, expected, b)
		}
	}
}
Exemple #15
0
func crt(N *big.Int, moduli map[int64]int64) *big.Int {
	// From Wikipedia CRT page
	x := new(big.Int)
	total := N
	for n, a := range moduli {
		N := new(big.Int).Set(total)
		N.Div(N, big.NewInt(n))
		N.ModInverse(N, big.NewInt(n))
		N.Mul(N, total)
		N.Div(N, big.NewInt(n))
		N.Mul(N, big.NewInt(a))
		x.Add(x, N)
		x.Mod(x, total)
	}
	return x
}
Exemple #16
0
// NewMember creates a new member private key for the group.
func (priv *PrivateKey) NewMember(r io.Reader) (*MemberKey, error) {
	mem := new(MemberKey)
	var err error

	mem.Group = priv.Group
	mem.x, err = randomZp(r)
	if err != nil {
		return nil, err
	}

	s := new(big.Int).Add(priv.gamma, mem.x)
	s.ModInverse(s, bn256.Order)
	mem.a = new(bn256.G1).ScalarMult(priv.g1, s)

	return mem, nil
}
Exemple #17
0
// Update alters mem to create a member private key for an updated Group. (Note
// that the Group of mem must also be updated.) This functions returns false if
// mem is the member private key that has been revoked.
func (mem *MemberKey) Update(r *Revocation) bool {
	if mem.x.Cmp(r.x) == 0 {
		return false
	}

	d := new(big.Int).Sub(mem.x, r.x)
	d.Mod(d, bn256.Order)
	d.ModInverse(d, bn256.Order)

	newA := new(bn256.G1).ScalarMult(r.a, d)
	t := new(bn256.G1).ScalarMult(mem.a, d)
	t.Neg(t)
	newA.Add(newA, t)

	mem.a = newA
	return true
}
func (calc *Calculator) twoValueCalculation(a, b *big.Int, operator string) *big.Int {
	switch operator {
	case "+":
		return a.Add(a, b)
	case "-":
		return a.Sub(a, b)
	case "*":
		return a.Mul(a, b)
	case "%":
		return a.Mod(a, b)
	case "/":
		return a.Div(a, b)
	case "$":
		return a.ModInverse(a, b)
	}

	return nil
}
Exemple #19
0
// ModInverse calculates the modular inverse of a over P
func (curve Curve) ModInverse(a *big.Int) (*big.Int, error) {
	// since P should be a prime, any GCD calculation is really a waste if a != P
	if a.Cmp(curve.Params.N) == 0 {
		return nil, ErrNotRelPrime
	}
	if a.Cmp(big.NewInt(1)) == 0 { // this should never happen
		return nil, ErrNotRelPrime
	}
	if a.Cmp(big.NewInt(0)) == 0 { // this should never happen
		return nil, ErrNotRelPrime
	}
	z := new(big.Int)
	z = z.GCD(nil, nil, a, curve.Params.N)
	if z.Cmp(big.NewInt(1)) == 0 {
		z = z.ModInverse(a, curve.Params.N)
		return z, nil
	}
	return nil, ErrNotRelPrime
}
Exemple #20
0
func RecoverPubKeyFromSignature(r, s *big.Int, msg []byte, curve *bitelliptic.BitCurve, recid uint) (qx, qy *big.Int, err error) {
	if recid > 3 {
		return nil, nil, fmt.Errorf("Illegal recid %v - must be in 0..3", recid)
	}
	order := curve.N
	i := recid / 2
	field := curve.P
	x := new(big.Int).Set(order)
	x.Mul(x, big.NewInt(int64(i)))
	x.Add(x, r)
	if x.Cmp(field) >= 0 {
		err = fmt.Errorf("%v >= %v", x, field)
		return
	}

	rx, ry, err := uncompressPoint(x, curve, 0 == (recid%2))
	if err != nil {
		return nil, nil, err
	}
	if !curve.IsOnCurve(rx, ry) {
		return nil, nil, fmt.Errorf("Point %d, %d not on curve", rx, ry)
	}

	e := new(big.Int).SetBytes(msg)
	if 8*len(msg) > curve.BitSize {
		e.Rsh(e, uint(8-(curve.BitSize&7)))
	}
	e.Neg(e).Mod(e, order)

	var rr, sor, eor big.Int
	rr.ModInverse(r, order)
	//return nil, nil, fmt.Errorf("r: %d, r_inv: %d", r, &rr)
	//Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r);
	sor.Mul(s, &rr)
	eor.Mul(e, &rr)

	Georx, Geory := curve.ScalarBaseMult(eor.Bytes())
	Rsorx, Rsory := curve.ScalarMult(rx, ry, sor.Bytes())
	qx, qy = curve.Add(Georx, Geory, Rsorx, Rsory)

	return
}
Exemple #21
0
// Returns an ECDSA instance for which Sign(m) == r, s and which will
// be in a subgroup of the same size as g.
func FindVerifyingECDSA(m []byte, r, s *big.Int, g CyclicGroup) ECDSA {
	n := g.Size()
	d := &ecdsa{g: g, key: new(big.Int)}
	for d.key.Cmp(new(big.Int)) == 0 {
		d.key.Rand(rnd, n)
	}
	h := sha1.New()
	if n, err := h.Write(m); n != len(m) || err != nil {
		log.Fatal("Error calculating hash")
	}
	e := h.Sum(nil)
	z := new(big.Int).SetBytes(e)
	z.Mod(z, n)
	w := new(big.Int).ModInverse(s, n)
	u1 := new(big.Int).Mul(z, w)
	u1.Mod(u1, n)
	u2 := new(big.Int).Mul(r, w)
	u2.Mod(u2, n)
	rr := new(big.Int).Set(r)
	t := new(big.Int).Mul(u2, d.key)
	t.Add(t, u1)
	t.ModInverse(t, n)
	// If we don't have the public key that actually generated the signature,
	// we need to guess what R was before doing r = R.x mod n
	for ; ; rr.Add(rr, g.Size()) {
		R, err := NewEllipticCurveElementFromX(g.(*generatedGroup).g, rr)
		if err != nil {
			continue
		}
		for _, invert := range []bool{false, true} {
			if invert {
				NegateWeierstrass(R, g.(*generatedGroup).g)
			}
			G := g.Pow(R, t)
			d.g = NewGeneratedGroup(g.(*generatedGroup).g, G, *d.g.Size())
			if ECDSAVerify(m, r, s, d) {
				return d
			}
		}
	}
}
Exemple #22
0
// GenerateGroup generates a new group and group private key.
func GenerateGroup(r io.Reader) (*PrivateKey, error) {
	priv := new(PrivateKey)
	priv.Group = new(Group)
	var err error

	if _, priv.g1, err = bn256.RandomG1(r); err != nil {
		return nil, err
	}
	if _, priv.g2, err = bn256.RandomG2(r); err != nil {
		return nil, err
	}
	if _, priv.h, err = bn256.RandomG1(r); err != nil {
		return nil, err
	}
	if priv.xi1, err = randomZp(r); err != nil {
		return nil, err
	}
	if priv.xi2, err = randomZp(r); err != nil {
		return nil, err
	}

	z0 := new(big.Int).ModInverse(priv.xi1, bn256.Order)
	priv.u = new(bn256.G1).ScalarMult(priv.h, z0)

	z0.ModInverse(priv.xi2, bn256.Order)
	priv.v = new(bn256.G1).ScalarMult(priv.h, z0)

	priv.gamma, err = randomZp(r)
	if err != nil {
		return nil, err
	}
	priv.w = new(bn256.G2).ScalarMult(priv.g2, priv.gamma)
	priv.precompute()

	return priv, nil
}
Exemple #23
0
func (c *Conversation) processSMP3(mpis []*big.Int) (out tlv, err error) {
	if len(mpis) != 8 {
		err = errors.New("otr: incorrect number of arguments in SMP3 message")
		return
	}
	pa := mpis[0]
	qa := mpis[1]
	cp := mpis[2]
	d5 := mpis[3]
	d6 := mpis[4]
	ra := mpis[5]
	cr := mpis[6]
	d7 := mpis[7]
	h := sha256.New()

	r := new(big.Int).Exp(g, d5, p)
	s := new(big.Int).Exp(c.smp.g2, d6, p)
	r.Mul(r, s)
	s.Exp(qa, cp, p)
	r.Mul(r, s)
	r.Mod(r, p)

	s.Exp(c.smp.g3, d5, p)
	t := new(big.Int).Exp(pa, cp, p)
	s.Mul(s, t)
	s.Mod(s, p)
	t.SetBytes(hashMPIs(h, 6, s, r))
	if t.Cmp(cp) != 0 {
		err = errors.New("otr: ZKP cP failed in SMP3 message")
		return
	}

	r.ModInverse(c.smp.qb, p)
	qaqb := new(big.Int).Mul(qa, r)
	qaqb.Mod(qaqb, p)

	r.Exp(qaqb, d7, p)
	s.Exp(ra, cr, p)
	r.Mul(r, s)
	r.Mod(r, p)

	s.Exp(g, d7, p)
	t.Exp(c.smp.g3a, cr, p)
	s.Mul(s, t)
	s.Mod(s, p)
	t.SetBytes(hashMPIs(h, 7, s, r))
	if t.Cmp(cr) != 0 {
		err = errors.New("otr: ZKP cR failed in SMP3 message")
		return
	}

	var randBuf [16]byte
	r7 := c.randMPI(randBuf[:])
	rb := new(big.Int).Exp(qaqb, c.smp.b3, p)

	r.Exp(qaqb, r7, p)
	s.Exp(g, r7, p)
	cr = new(big.Int).SetBytes(hashMPIs(h, 8, s, r))

	r.Mul(c.smp.b3, cr)
	d7 = new(big.Int).Sub(r7, r)
	d7.Mod(d7, q)
	if d7.Sign() < 0 {
		d7.Add(d7, q)
	}

	out.typ = tlvTypeSMP4
	out.data = appendU32(out.data, 3)
	out.data = appendMPIs(out.data, rb, cr, d7)

	r.ModInverse(c.smp.pb, p)
	r.Mul(pa, r)
	r.Mod(r, p)
	s.Exp(ra, c.smp.b3, p)
	if r.Cmp(s) != 0 {
		err = smpFailureError
	}

	return
}
Exemple #24
0
func recoverKey(sigA, sigB *btcec.Signature, hashA, hashB []byte, pubKey *btcec.PublicKey) *btcec.PrivateKey {
	// Sanity checks
	if sigA.R.Cmp(sigB.R) != 0 {
		log.Println("Different R!")
		return nil
	}
	if !ecdsa.Verify(pubKey.ToECDSA(), hashA, sigA.R, sigA.S) {
		log.Println("A fails to verify!")
		return nil
	}
	if !ecdsa.Verify(pubKey.ToECDSA(), hashB, sigB.R, sigB.S) {
		log.Println("B fails to verify!")
		return nil
	}
	if !reflect.DeepEqual(pubKey.Curve, btcec.S256()) {
		log.Println("What the curve?!")
		return nil
	}

	c := btcec.S256()

	N := c.Params().N
	zA := hashToInt(hashA, c)
	zB := hashToInt(hashB, c)

	sDiffInv := new(big.Int).Sub(sigA.S, sigB.S)
	sDiffInv.Mod(sDiffInv, N)
	sDiffInv.ModInverse(sDiffInv, N)

	zDiff := new(big.Int).Sub(zA, zB)
	zDiff.Mod(zDiff, N)

	k := new(big.Int).Mul(zDiff, sDiffInv)
	k.Mod(k, N)

	rInv := new(big.Int).ModInverse(sigA.R, N)

	D := new(big.Int)
	D.Mul(sigA.S, k)
	D.Sub(D, zA)
	D.Mul(D, rInv)
	D.Mod(D, N)

	x, y := c.ScalarBaseMult(D.Bytes())
	if pubKey.X.Cmp(x) != 0 {
		log.Println("X!")
		return nil
	}
	if pubKey.Y.Cmp(y) != 0 {
		log.Println("Y!")
		return nil
	}

	return &btcec.PrivateKey{
		PublicKey: ecdsa.PublicKey{
			Curve: c,
			X:     x,
			Y:     y,
		},
		D: D,
	}
}
Exemple #25
0
func main() {

	scanner := bufio.NewScanner(os.Stdin)

	var z big.Int
	var a, b, c big.Int
	var r big.Int

	two := big.NewInt(2)

	var n_add, n_sub, n_mul2, n_div2, n_gcd, n_sqr, n_invmod, n_exptmod int

	for scanner.Scan() {
		cmd := scanner.Text()

		fmt.Println(n_add, n_sub, n_mul2, n_div2, n_gcd, n_sqr, n_invmod)

		switch cmd {

		case "add_d", "add":
			n_add++
			next(scanner, &a)
			next(scanner, &b)
			next(scanner, &r)

			z.Add(&a, &b)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		case "sub_d", "sub":
			n_sub++
			next(scanner, &a)
			next(scanner, &b)
			next(scanner, &r)

			z.Sub(&a, &b)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		case "mul2":
			n_mul2++
			next(scanner, &a)
			next(scanner, &r)

			z.Mul(&a, two)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		case "div2":
			n_div2++
			next(scanner, &a)
			next(scanner, &r)

			z.Div(&a, two)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}
		case "sqr":
			n_sqr++
			next(scanner, &a)
			next(scanner, &r)

			z.Mul(&a, &a)
			if false && z.Cmp(&r) != 0 {
				fmt.Printf("sqr: %s %s %s\n", a.String(), r.String(), z.String())
			}

		case "gcd":
			n_gcd++
			next(scanner, &a)
			next(scanner, &b)
			next(scanner, &r)

			z.GCD(nil, nil, &a, &b)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		case "invmod":
			n_invmod++
			next(scanner, &a)
			next(scanner, &b)
			next(scanner, &r)

			z.ModInverse(&a, &b)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		case "exptmod":
			n_exptmod++
			next(scanner, &a)
			next(scanner, &b)
			next(scanner, &c)
			next(scanner, &r)

			z.Exp(&a, &b, &c)
			if z.Cmp(&r) != 0 {
				fmt.Println(a, b, r, z)
			}

		default:
			// nothing
		}
	}
}
Exemple #26
0
func main() {
	p, _ := new(big.Int).SetString("233970423115425145524320034830162017933", 10)
	a := big.NewInt(-95051)
	//a.Sub(p, a)
	b := big.NewInt(11279326)
	G := dh.NewEllipticCurve(a, b, p)

	gx := big.NewInt(182)
	gy, _ := new(big.Int).SetString("85518893674295321206118380980485522083", 10)
	g := dh.NewEllipticCurveElement(G, gx, gy)
	q, _ := new(big.Int).SetString("29246302889428143187362802287225875743", 10)
	GG := dh.NewGeneratedGroup(G, g, *q)

	d1 := dh.NewDiffieHellman(GG)
	d2 := dh.NewDiffieHellman(GG)

	fmt.Printf("=== PHASE I: TEST DIFFIE-HELLMAN WORKS ===\n")

	log.Printf("Alice's DH: %s", d1)
	log.Printf("Bob's DH: %s", d2)

	log.Printf("Bob's shared secret from Alice's public key: %s", d2.SharedSecret(d1.PublicKey()))
	log.Printf("Alice's shared secret from Bob's public key: %s", d1.SharedSecret(d2.PublicKey()))

	fmt.Printf("=== PHASE II: BREAK DIFFIE-HELLMAN ===\n")

	weakSubgroups := []dh.Group{
		dh.NewEllipticCurve(big.NewInt(-95051), big.NewInt(210), p),
		dh.NewEllipticCurve(big.NewInt(-95051), big.NewInt(504), p),
		dh.NewEllipticCurve(big.NewInt(-95051), big.NewInt(727), p),
	}
	weakSubgroupOrders := make([]*big.Int, 3)
	weakSubgroupOrders[0], _ = new(big.Int).SetString("233970423115425145550826547352470124412", 10)
	weakSubgroupOrders[1], _ = new(big.Int).SetString("233970423115425145544350131142039591210", 10)
	weakSubgroupOrders[2], _ = new(big.Int).SetString("233970423115425145545378039958152057148", 10)

	allFactors := make(map[int64]dh.Element)

	for i, SG := range weakSubgroups {
		order := weakSubgroupOrders[i]
		factors := dh.FindFactors(order, order, q, SG)
		for factor, h := range factors {
			if _, ok := allFactors[factor]; !ok {
				allFactors[factor] = h
			}
		}
	}

	moduli := make(map[int64]int64)
	total := big.NewInt(1)

	d := dh.NewDiffieHellman(GG)
	for factor, h := range allFactors {
		mac := Bob(d, h)
		log.Printf("Guessing the shared secret in the subgroup of order %d", factor)
		found := false
		for i := int64(1); i <= factor; i++ {
			k := G.Pow(h, big.NewInt(i))
			if hmac.Equal(mac, Sign(secretMessage, k)) {
				found = true
				moduli[factor] = i
				break
			}
		}
		if found {
			total.Mul(total, big.NewInt(factor))
			if total.Cmp(q) > 0 {
				log.Printf("Found enough moduli")
				break
			}
		} else {
			// This can happen if a prime factor of one of the weak subgroups' order
			// is a double divisor in another one's order.
			log.Printf("Could not guess the shared secret!")
		}
	}

	// From Wikipedia CRT page
	x := new(big.Int)
	for n, a := range moduli {
		N := new(big.Int).Set(total)
		N.Div(N, big.NewInt(n))
		N.ModInverse(N, big.NewInt(n))
		N.Mul(N, total)
		N.Div(N, big.NewInt(n))
		N.Mul(N, big.NewInt(a))
		x.Add(x, N)
		x.Mod(x, total)
	}
	log.Printf("Predicted key: %d", x)

	log.Printf("%s", d)
}
Exemple #27
0
func main() {
	fmt.Printf("=== PHASE I: TEST ALGORITHM ===\n")
	pi := new(big.Int)
	pi.SetString("11470374874925275658116663507232161402086650258453896274534991676898999262641581519101074740642369848233294239851519212341844337347119899874391456329785623", 10)
	gi := new(big.Int)
	gi.SetString("622952335333961296978159266084741085889881358738459939978290179936063635566740258555167783009058567397963466103140082647486611657350811560630587013183357", 10)
	q := new(big.Int)
	q.SetString("335062023296420808191071248367701059461", 10)
	G := dh.NewFiniteGroup(*pi)
	g := dh.NewFiniteElement(G, *gi)
	GG := dh.NewGeneratedGroup(G, g, *q)

	targets := []string{
		"7760073848032689505395005705677365876654629189298052775754597607446617558600394076764814236081991643094239886772481052254010323780165093955236429914607119",
		"9388897478013399550694114614498790691034187453089355259602614074132918843899833277397448144245883225611726912025846772975325932794909655215329941809013733",
	}

	hi := new(big.Int)
	a := 0
	upperBounds := []int{1 << 20, 1 << 40}

	for i, hs := range targets {
		hi.SetString(hs, 10)
		b := upperBounds[i]

		h := dh.NewFiniteElement(G, *hi)

		log.Printf("Searching for discrete log of %s", h)
		x := dh.Pollard(GG, g, h, a, b)
		if x == nil {
			log.Printf("The wild kangaroo escaped!")
		} else {
			x.Mod(x, q)
			log.Printf("discrete log = %s", x)
			check := GG.Pow(g, x)
			log.Printf("%s^%d mod %s == %s", g, x, pi, GG.Pow(g, x))
			if check.Cmp(h) != 0 {
				log.Printf("ERROR! Expected %s but got %s", h, check)
			}
		}
	}

	fmt.Printf("\n=== PHASE II: APPLY WITH COFACTOR ATTACK ===\n")
	factors := dh.FindCoFactors(q, pi, G)

	moduli := make(map[int64]int64)
	total := big.NewInt(1)

	d := dh.NewDiffieHellman(GG)
	for factor, h := range factors {
		total.Mul(total, big.NewInt(factor))
		mac := Bob(d, h)
		log.Printf("Guessing the shared secret in the subgroup of order %d", factor)
		found := false
		for i := int64(1); i <= factor; i++ {
			k := G.Pow(h, big.NewInt(i))
			if hmac.Equal(mac, Sign(secretMessage, k)) {
				//log.Printf("%d^%d", elt, i)
				found = true
				moduli[factor] = i
				break
			}
		}
		if !found {
			panic("Could not guess the shared secret")
		}
	}

	// From Wikipedia CRT page
	x := new(big.Int)
	for n, a := range moduli {
		N := new(big.Int).Set(total)
		N.Div(N, big.NewInt(n))
		N.ModInverse(N, big.NewInt(n))
		N.Mul(N, total)
		N.Div(N, big.NewInt(n))
		N.Mul(N, big.NewInt(a))
		x.Add(x, N)
		x.Mod(x, total)
	}
	log.Printf("x mod r = %s [r = %s]", x, total)

	n := new(big.Int)
	n.Sub(q, x)

	hp := GG.Op(d.PublicKey(), GG.Pow(g, n))
	gp := GG.Pow(g, total)
	B := new(big.Int)
	B.Div(q, total)

	log.Printf("Searching for discrete log of %s", hp)
	m := dh.Pollard(GG, gp, hp, 0, int(B.Int64()))
	if m == nil {
		log.Printf("The wild kangaroo escaped!")
	} else {
		m.Mod(m, q)
		log.Printf("discrete log = %s", m)
		check := GG.Pow(gp, m)
		log.Printf("%s^%d mod %s == %s", gp, m, pi, GG.Pow(gp, m))
		if check.Cmp(hp) != 0 {
			log.Printf("ERROR! Expected %s but got %s", hp, check)
		}
	}

	m.Mul(m, total)
	x.Add(x, m)

	log.Printf("Predicted key: %d", x)
	log.Printf("%s", d)
}
Exemple #28
0
func main() {
	p, _ := new(big.Int).SetString("233970423115425145524320034830162017933", 10)
	groupOrder, _ := new(big.Int).SetString("233970423115425145498902418297807005944", 10)
	a := big.NewInt(-95051)
	b := big.NewInt(11279326)
	EC := dh.NewEllipticCurve(a, b, p)
	gx := big.NewInt(182)
	gy, _ := new(big.Int).SetString("85518893674295321206118380980485522083", 10)
	g := dh.NewEllipticCurveElement(EC, gx, gy)

	MC := dh.NewMontgomeryCurve(big.NewInt(534), big.NewInt(1), p)
	mg := dh.NewMontgomeryCurveElement(MC, big.NewInt(4))
	q, _ := new(big.Int).SetString("29246302889428143187362802287225875743", 10)
	GG := dh.NewGeneratedGroup(MC, mg, *q)

	twistOrder := new(big.Int).Mul(p, big.NewInt(2))
	twistOrder.Add(twistOrder, big.NewInt(2))
	twistOrder.Sub(twistOrder, groupOrder)

	factors := dh.FindFactors(twistOrder, twistOrder, q, MC)

	total := big.NewInt(1)

	for factor, _ := range factors {
		total.Mul(total, big.NewInt(factor))
	}

	// Find an element that is order=total. We will use this to guess which
	// of the one or two remainders for each small prime is correct.
	log.Printf("Finding an element of order %d...", total)
	pow := new(big.Int)
	pow.Div(twistOrder, total)
	var h dh.Element = nil
	for {
		h = MC.Pow(MC.Random(), pow)
		if h.Cmp(MC.Identity()) != 0 {
			bad := false
			for factor, _ := range factors {
				if MC.Pow(h, big.NewInt(factor)).Cmp(MC.Identity()) == 0 {
					bad = true
					break
				}
			}
			if !bad {
				log.Printf("%s^%d == %s", h, total, MC.Pow(h, total))
				break
			}
		}
	}

	d := dh.NewDiffieHellman(GG)
	mac := Alice(d, h)

	// Determine the possible remainders for each small prime. There are usually
	// two because (u, v) and (u, -v) are conflated by the ladder.
	type factorModuli struct {
		factor         int64
		possibleModuli []int64
	}
	smallFactorModuli := make([]*factorModuli, 0)
	for factor, h := range factors {
		fm := &factorModuli{factor, make([]int64, 0)}
		mac := Alice(d, h)
		log.Printf("Guessing the shared secret in the subgroup of order %d", factor)
		found := false
		for i := int64(0); i < factor; i++ {
			k := MC.Pow(h, big.NewInt(i))
			if hmac.Equal(mac, Sign(secretMessage, k)) {
				found = true
				fm.possibleModuli = append(fm.possibleModuli, i)
				if i != 0 {
					// If h^i = (u, v) then (u, -v) = (h^i)^-1 = h^-i
					fm.possibleModuli = append(fm.possibleModuli, factor-i)
				}
				break
			}
		}
		if !found {
			log.Fatal("Could not guess the shared secret")
		}
		smallFactorModuli = append(smallFactorModuli, fm)
	}

	// Figure out which one of the various choices for each small remainder is correct.
	// For each permutation:
	//  - use CRT to compute remainder x mod "total"
	//  - check if the saved MAC corresponds to h^x.
	indices := make([]int, len(smallFactorModuli))
	bigModuli := make([]*big.Int, 0)
	for {
		carry := true
		for i := 0; carry && i < len(indices); i++ {
			indices[i] = (indices[i] + 1) % len(smallFactorModuli[i].possibleModuli)
			carry = indices[i] == 0
		}
		moduli := make(map[int64]int64)
		for i, fm := range smallFactorModuli {
			moduli[fm.factor] = fm.possibleModuli[indices[i]]
		}
		// From Wikipedia CRT page
		x := new(big.Int)
		for n, a := range moduli {
			N := new(big.Int).Set(total)
			N.Div(N, big.NewInt(n))
			N.ModInverse(N, big.NewInt(n))
			N.Mul(N, total)
			N.Div(N, big.NewInt(n))
			N.Mul(N, big.NewInt(a))
			x.Add(x, N)
			x.Mod(x, total)
		}
		k := MC.Pow(h, x)
		if hmac.Equal(mac, Sign(secretMessage, k)) {
			log.Printf("x mod r may be %s [r = %s]", x, total)
			bigModuli = append(bigModuli, x)
			if x.Cmp(new(big.Int)) != 0 {
				// Again there are probably two answers, because
				// h^x = h^-x using the montgomery ladder.
				y := new(big.Int).Sub(total, x)
				log.Printf("x mod r may be %s [r = %s]", y, total)
				bigModuli = append(bigModuli, y)
			}
			break
		}
	}

	// We now have two possible remainders mod "total". For each of those,
	// use the kangaroo algorithm to try to guess the secret. Note that
	// the public key that Alice gives us will *also* correspond to two
	// different points (u, v) and (u, -v) so we need to try plugging both
	// of them in and see which one works.
	ch := make(chan bool)
	for _, x := range bigModuli {
		for _, negate := range []bool{true, false} {
			go func(x *big.Int, negate bool) {
				n := new(big.Int)
				n.Sub(q, x)

				// Convert to Weierstrass form so Op is implemented and so
				// we can specify which of the two collapsed points (u, v)
				// and (u, -v) to use for this trial.
				w1 := dh.Q60MontgomeryToWeierstrass(d.PublicKey(), EC)
				if negate {
					dh.NegateWeierstrass(w1, EC)
				}
				w2 := EC.Pow(g, n)
				hp := EC.Op(w1, w2)
				gp := EC.Pow(g, total)
				B := new(big.Int)
				B.Div(q, total)

				log.Printf("Searching for index of %s in 0..%d", hp, B.Int64())
				m := dh.Pollard(EC, gp, hp, 0, int(B.Int64()))
				if m == nil {
					log.Printf("The wild kangaroo escaped!")
					return
				} else {
					m.Mod(m, q)
					log.Printf("index = %s", m)
					check := EC.Pow(gp, m)
					log.Printf("%s^%d mod %s = %s", gp, m, p, check)
					if check.Cmp(hp) != 0 {
						log.Printf("ERROR! Expected %s but got %s", hp, check)
					}
				}

				m.Mul(m, total)
				x.Add(x, m)

				log.Printf("Predicted key: %d", x)
				log.Printf("%s", d)
				ch <- true
			}(x, negate)
		}
	}

	<-ch
}
Exemple #29
0
func (c *Conversation) processSMP2(mpis []*big.Int) (out tlv, err error) {
	if len(mpis) != 11 {
		err = errors.New("otr: incorrect number of arguments in SMP2 message")
		return
	}
	g2b := mpis[0]
	c2 := mpis[1]
	d2 := mpis[2]
	g3b := mpis[3]
	c3 := mpis[4]
	d3 := mpis[5]
	pb := mpis[6]
	qb := mpis[7]
	cp := mpis[8]
	d5 := mpis[9]
	d6 := mpis[10]
	h := sha256.New()

	r := new(big.Int).Exp(g, d2, p)
	s := new(big.Int).Exp(g2b, c2, p)
	r.Mul(r, s)
	r.Mod(r, p)
	s.SetBytes(hashMPIs(h, 3, r))
	if c2.Cmp(s) != 0 {
		err = errors.New("otr: ZKP c2 failed in SMP2 message")
		return
	}

	r.Exp(g, d3, p)
	s.Exp(g3b, c3, p)
	r.Mul(r, s)
	r.Mod(r, p)
	s.SetBytes(hashMPIs(h, 4, r))
	if c3.Cmp(s) != 0 {
		err = errors.New("otr: ZKP c3 failed in SMP2 message")
		return
	}

	c.smp.g2 = new(big.Int).Exp(g2b, c.smp.a2, p)
	c.smp.g3 = new(big.Int).Exp(g3b, c.smp.a3, p)

	r.Exp(g, d5, p)
	s.Exp(c.smp.g2, d6, p)
	r.Mul(r, s)
	s.Exp(qb, cp, p)
	r.Mul(r, s)
	r.Mod(r, p)

	s.Exp(c.smp.g3, d5, p)
	t := new(big.Int).Exp(pb, cp, p)
	s.Mul(s, t)
	s.Mod(s, p)
	t.SetBytes(hashMPIs(h, 5, s, r))
	if cp.Cmp(t) != 0 {
		err = errors.New("otr: ZKP cP failed in SMP2 message")
		return
	}

	var randBuf [16]byte
	r4 := c.randMPI(randBuf[:])
	r5 := c.randMPI(randBuf[:])
	r6 := c.randMPI(randBuf[:])
	r7 := c.randMPI(randBuf[:])

	pa := new(big.Int).Exp(c.smp.g3, r4, p)
	r.Exp(c.smp.g2, c.smp.secret, p)
	qa := new(big.Int).Exp(g, r4, p)
	qa.Mul(qa, r)
	qa.Mod(qa, p)

	r.Exp(g, r5, p)
	s.Exp(c.smp.g2, r6, p)
	r.Mul(r, s)
	r.Mod(r, p)

	s.Exp(c.smp.g3, r5, p)
	cp.SetBytes(hashMPIs(h, 6, s, r))

	r.Mul(r4, cp)
	d5 = new(big.Int).Sub(r5, r)
	d5.Mod(d5, q)
	if d5.Sign() < 0 {
		d5.Add(d5, q)
	}

	r.Mul(c.smp.secret, cp)
	d6 = new(big.Int).Sub(r6, r)
	d6.Mod(d6, q)
	if d6.Sign() < 0 {
		d6.Add(d6, q)
	}

	r.ModInverse(qb, p)
	qaqb := new(big.Int).Mul(qa, r)
	qaqb.Mod(qaqb, p)

	ra := new(big.Int).Exp(qaqb, c.smp.a3, p)
	r.Exp(qaqb, r7, p)
	s.Exp(g, r7, p)
	cr := new(big.Int).SetBytes(hashMPIs(h, 7, s, r))

	r.Mul(c.smp.a3, cr)
	d7 := new(big.Int).Sub(r7, r)
	d7.Mod(d7, q)
	if d7.Sign() < 0 {
		d7.Add(d7, q)
	}

	c.smp.g3b = g3b
	c.smp.qaqb = qaqb

	r.ModInverse(pb, p)
	c.smp.papb = new(big.Int).Mul(pa, r)
	c.smp.papb.Mod(c.smp.papb, p)
	c.smp.ra = ra

	out.typ = tlvTypeSMP3
	out.data = appendU32(out.data, 8)
	out.data = appendMPIs(out.data, pa, qa, cp, d5, d6, ra, cr, d7)
	return
}