// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. // The OID for the named curve may be provided from another source (such as // the PKCS8 container) - if it is provided then use this instead of the OID // that may exist in the EC private key structure. func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { var privKey ecPrivateKey if _, err := asn1.Unmarshal(der, &privKey); err != nil { return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) } if privKey.Version != ecPrivKeyVersion { return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) } var curve elliptic.Curve if namedCurveOID != nil { curve = namedCurveFromOID(*namedCurveOID) } else { curve = namedCurveFromOID(privKey.NamedCurveOID) } if curve == nil { return nil, errors.New("x509: unknown elliptic curve") } k := new(big.Int).SetBytes(privKey.PrivateKey) if k.Cmp(curve.Params().N) >= 0 { return nil, errors.New("x509: invalid elliptic curve private key value") } priv := new(ecdsa.PrivateKey) priv.Curve = curve priv.D = k priv.X, priv.Y = curve.ScalarBaseMult(privKey.PrivateKey) return priv, nil }
func hashG(c elliptic.Curve, m []byte) (hx, hy *big.Int) { h := sha256.New() h.Write(m) d := h.Sum(nil) hx, hy = c.ScalarBaseMult(d) // g^H'() return }
func VoteOne(c elliptic.Curve, px *big.Int, py *big.Int) *Checkbox { var err error h := new(Checkbox) h.s, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } h.ax, h.ay = c.ScalarBaseMult(h.s.Bytes()) tx, ty := c.ScalarMult(px, py, h.s.Bytes()) h.bx, h.by = c.Add(tx, ty, c.Params().Gx, c.Params().Gy) //TODO: refactor: lots of similar logic here but parts very //c2, r2 fake, c1 r1 genuine //Form the faked challenge h.c2, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } h.r2, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } //Compute the commitments v3, v4 as the verifier will v3x, v3y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, h.r2.Bytes(), h.ax, h.ay, h.c2.Bytes()) v4x, v4y := doublescalarmult(c, px, py, h.r2.Bytes(), h.bx, h.by, h.c2.Bytes()) //Commit to other side s1, err := rand.Int(rand.Reader, c.Params().N) if err != nil { panic("something deeply wrong") } v1x, v1y := c.ScalarBaseMult(s1.Bytes()) v2x, v2y := c.ScalarMult(px, py, s1.Bytes()) //Compute the total challenge var entries [6][]byte entries[0] = elliptic.Marshal(c, h.ax, h.ay) entries[1] = elliptic.Marshal(c, h.bx, h.by) entries[2] = elliptic.Marshal(c, v1x, v1y) entries[3] = elliptic.Marshal(c, v2x, v2y) entries[4] = elliptic.Marshal(c, v3x, v3y) entries[5] = elliptic.Marshal(c, v4x, v4y) challenge := sha256.Sum256(bytes.Join(entries[:], []byte{})) ctot := big.NewInt(0) ctot.SetBytes(challenge[:]) ctot.Mod(ctot, c.Params().N) h.c1 = big.NewInt(0) h.c1.Sub(ctot, h.c2) h.c1.Mod(h.c1, c.Params().N) //r=s1-c1*h.s t := big.NewInt(0) t.Mul(h.c1, h.s) t.Mod(t, c.Params().N) t.Sub(s1, t) t.Mod(t, c.Params().N) h.r1 = t return h }
// GenerateKey generates a public and private key pair. func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) { k, err := randFieldElement(c, rand) if err != nil { return } priv = new(PrivateKey) priv.PublicKey.Curve = c priv.D = k priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) return }
func DiscreteLog(x *big.Int, y *big.Int, c elliptic.Curve, bound int) (int, error) { var xprime *big.Int var yprime *big.Int if x.Cmp(big.NewInt(0)) == 0 && y.Cmp(big.NewInt(0)) == 0 { return 0, nil } for i := 0; i < bound; i++ { xprime, yprime = c.ScalarBaseMult(big.NewInt(int64(i)).Bytes()) if xprime.Cmp(x) == 0 && yprime.Cmp(y) == 0 { return i, nil } } return -1, errors.New("log not found") }
func FillBallot(c elliptic.Curve, px *big.Int, py *big.Int, entry int, size int) *Ballot { b := new(Ballot) b.boxes = make([]*Checkbox, size, size) for i := 0; i < size; i++ { if i == entry { b.boxes[i] = VoteOne(c, px, py) } else { b.boxes[i] = VoteZero(c, px, py) } } //TODO: add validation //Let A be the sum of all the A, B the sum of all the B //Then we want log_g(A)=log_h(B-g) ax := big.NewInt(0) ay := big.NewInt(0) bx := big.NewInt(0) by := big.NewInt(0) s := big.NewInt(0) for i := 0; i < size; i++ { ax, ay = c.Add(ax, ay, b.boxes[i].ax, b.boxes[i].ay) bx, by = c.Add(bx, by, b.boxes[i].bx, b.boxes[i].by) s.Add(s, b.boxes[i].s) } s.Mod(s, c.Params().N) k, err := rand.Int(rand.Reader, c.Params().N) if err != nil { panic("Not here, not now") } v1x, v1y := c.ScalarBaseMult(k.Bytes()) v2x, v2y := c.ScalarMult(px, py, k.Bytes()) var commit [4][]byte commit[0] = elliptic.Marshal(c, ax, ay) commit[1] = elliptic.Marshal(c, bx, by) commit[2] = elliptic.Marshal(c, v1x, v1y) commit[3] = elliptic.Marshal(c, v2x, v2y) cb := bytes.Join(commit[:], []byte{}) cbytes := sha256.Sum256(cb[:]) b.c = big.NewInt(0) b.c.SetBytes(cbytes[:]) b.c.Mod(b.c, c.Params().N) b.r = big.NewInt(0) //r=k-c*s b.r.Mul(b.c, s) b.r.Sub(k, b.r) b.r.Mod(b.r, c.Params().N) return b }
// PrivKeyFromBytes returns a private and public key for `curve' based on the // private key passed as an argument as a byte slice. func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey, *PublicKey) { x, y := curve.ScalarBaseMult(pk) priv := &ecdsa.PrivateKey{ PublicKey: ecdsa.PublicKey{ Curve: curve, X: x, Y: y, }, D: new(big.Int).SetBytes(pk), } return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey) }
// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. // The OID for the named curve may be provided from another source (such as // the PKCS8 container) - if it is provided then use this instead of the OID // that may exist in the EC private key structure. func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { var privKey ecPrivateKey if _, err := asn1.Unmarshal(der, &privKey); err != nil { return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) } if privKey.Version != ecPrivKeyVersion { return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) } var curve elliptic.Curve if namedCurveOID != nil { curve = namedCurveFromOID(*namedCurveOID) } else { curve = namedCurveFromOID(privKey.NamedCurveOID) } if curve == nil { return nil, errors.New("x509: unknown elliptic curve") } k := new(big.Int).SetBytes(privKey.PrivateKey) curveOrder := curve.Params().N if k.Cmp(curveOrder) >= 0 { return nil, errors.New("x509: invalid elliptic curve private key value") } priv := new(ecdsa.PrivateKey) priv.Curve = curve priv.D = k privateKey := make([]byte, (curveOrder.BitLen()+7)/8) // Some private keys have leading zero padding. This is invalid // according to [SEC1], but this code will ignore it. for len(privKey.PrivateKey) > len(privateKey) { if privKey.PrivateKey[0] != 0 { return nil, errors.New("x509: invalid private key length") } privKey.PrivateKey = privKey.PrivateKey[1:] } // Some private keys remove all leading zeros, this is also invalid // according to [SEC1] but since OpenSSL used to do this, we ignore // this too. copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) priv.X, priv.Y = curve.ScalarBaseMult(privateKey) return priv, nil }
func VoteZero(c elliptic.Curve, px *big.Int, py *big.Int) *Checkbox { var err error h := new(Checkbox) h.s, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } h.ax, h.ay = c.ScalarBaseMult(h.s.Bytes()) h.bx, h.by = c.ScalarMult(px, py, h.s.Bytes()) //TODO: get the proof generated //c1, r1 fake, c2, r2 genuine //First compute the missing B-g tx := big.NewInt(0) tx.Set(c.Params().Gx) ty := big.NewInt(0) ty.Set(c.Params().Gy) ty.Neg(ty) ty.Mod(ty, c.Params().P) bgx, bgy := c.Add(tx, ty, h.bx, h.by) //Now fake the challenge h.c1, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } h.r1, err = rand.Int(rand.Reader, c.Params().N) if err != nil { panic("this shouldn't happen") } //Compute v1, v2 as verifier will v1x, v1y := doublescalarmult(c, c.Params().Gx, c.Params().Gy, h.r1.Bytes(), h.ax, h.ay, h.c1.Bytes()) v2x, v2y := doublescalarmult(c, px, py, h.r1.Bytes(), bgx, bgy, h.c1.Bytes()) //Other part of commitment s1, err := rand.Int(rand.Reader, c.Params().N) if err != nil { panic("something is deeply wrong") } v3x, v3y := c.ScalarBaseMult(s1.Bytes()) v4x, v4y := c.ScalarMult(px, py, s1.Bytes()) //Compute total challenge var entries [6][]byte entries[0] = elliptic.Marshal(c, h.ax, h.ay) entries[1] = elliptic.Marshal(c, h.bx, h.by) entries[2] = elliptic.Marshal(c, v1x, v1y) entries[3] = elliptic.Marshal(c, v2x, v2y) entries[4] = elliptic.Marshal(c, v3x, v3y) entries[5] = elliptic.Marshal(c, v4x, v4y) challenge := sha256.Sum256(bytes.Join(entries[:], []byte{})) ctot := big.NewInt(0) ctot.SetBytes(challenge[:]) ctot.Mod(ctot, c.Params().N) h.c2 = big.NewInt(0) h.c2.Sub(ctot, h.c1) h.c2.Mod(h.c2, c.Params().N) //r2=s1-c2*s h.r2 = big.NewInt(0) h.r2.Mul(h.c2, h.s) h.r2.Sub(s1, h.r2) h.r2.Mod(h.r2, c.Params().N) return h }
func testScalarBaseMult(curve elliptic.Curve, k, ex, ey *big.Int) bool { x, y := curve.ScalarBaseMult(k.Bytes()) return x.Cmp(ex) == 0 && y.Cmp(ey) == 0 }