func namedCurveFromOID(oid asn1.ObjectIdentifier) *bitelliptic.BitCurve { switch { case oid.Equal(oidNamedCurveS256): return bitelliptic.S256() } return nil }
func oidFromNamedCurve(curve *bitelliptic.BitCurve) (asn1.ObjectIdentifier, bool) { switch curve { case bitelliptic.S256(): return oidNamedCurveS256, true } return nil, false }
func (k *Key) Sign(data []byte) (*big.Int, *big.Int) { key := bitecdsa.NewKeyFromInt(bitelliptic.S256(), k.prvKey) r, s, err := bitecdsa.Sign(rand.Reader, key, data) if err != nil { panic(err.Error()) } return r, s }
func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, bitelliptic.S256(), "S256") if testing.Short() { return } testKeyGeneration(t, bitelliptic.S160(), "S160") testKeyGeneration(t, bitelliptic.S192(), "S192") testKeyGeneration(t, bitelliptic.S224(), "S224") }
func TestSignAndVerify(t *testing.T) { testSignAndVerify(t, bitelliptic.S256(), "S256") if testing.Short() { return } testSignAndVerify(t, bitelliptic.S160(), "S160") testSignAndVerify(t, bitelliptic.S192(), "S192") testSignAndVerify(t, bitelliptic.S224(), "S224") }
func BenchmarkSign(b *testing.B) { b.StopTimer() priv, _ := GenerateKey(bitelliptic.S256(), rand.Reader) hashed := []byte("testing") b.StartTimer() for i := 0; i < b.N; i++ { Sign(rand.Reader, priv, hashed) } }
// MarshalECPrivateKey marshals an EC private key into ASN.1, DER format. func MarshalECPrivateKey(key *bitecdsa.PrivateKey) ([]byte, error) { // TODO(runeaune): Get the actual curve. oid, ok := oidFromNamedCurve(bitelliptic.S256()) if !ok { return nil, errors.New("x509: unknown elliptic curve") } return asn1.Marshal(ecPrivateKey{ Version: 1, PrivateKey: key.D.Bytes(), NamedCurveOID: oid, PublicKey: asn1.BitString{Bytes: key.Marshal(key.X, key.Y)}, }) }
func TestSerializeParseCompressedRandom(t *testing.T) { // Deterministic source of "random" numbers. r := rand.New(rand.NewSource(0)) for i := 0; i < 25; i++ { // Compressed storage is unable to represent arbitrary Ys, // every (x,y) point must correspond to a point on the curve // or we won't be able to recover it. key := randomData(r, 32) x, y := bitelliptic.S256().ScalarBaseMult(key) if !bitelliptic.S256().IsOnCurve(x, y) { t.Fatalf("Point (%v,%v) isn't on the curve.", x, y) } data := SerializeCompact(point{x, y}) p := ParseCompact(data) if x.Cmp(p.x) != 0 { t.Errorf("Test %d: X changed: got %v, expected %v (random data: %x).", i, p.x, x, key) } if y.Cmp(p.y) != 0 { t.Errorf("Test %d: Y changed: got %v, expected %v (random data: %x).", i, p.y, y, key) } } }
func BenchmarkVerify(b *testing.B) { b.StopTimer() data := testVectors[0] pub := &PublicKey{ BitCurve: bitelliptic.S256(), X: fromHex(data.Qx), Y: fromHex(data.Qy), } hashed, _ := base64.StdEncoding.DecodeString(data.hash) r := fromHex(data.r) s := fromHex(data.s) b.StartTimer() for i := 0; i < b.N; i++ { Verify(pub, hashed, r, s) } }
func TestVectors256(t *testing.T) { for i, test := range testVectors { pub := PublicKey{ BitCurve: bitelliptic.S256(), X: fromHex(test.Qx), Y: fromHex(test.Qy), } hashed, _ := base64.StdEncoding.DecodeString(test.hash) r := fromHex(test.r) s := fromHex(test.s) if Verify(&pub, hashed, r, s) != test.ok { t.Errorf("%d: bad result", i) } if testing.Short() { break } } }
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { switch pub := pub.(type) { case *bitecdsa.PublicKey: publicKeyBytes = pub.Marshal(pub.X, pub.Y) // TODO(runeaune): Get the actual curve. oid, ok := oidFromNamedCurve(bitelliptic.S256()) if !ok { return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") } publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA var paramBytes []byte paramBytes, err = asn1.Marshal(oid) if err != nil { return } publicKeyAlgorithm.Parameters.FullBytes = paramBytes default: return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only ECDSA public keys supported") } return publicKeyBytes, publicKeyAlgorithm, nil }
func TestSerializeParseCompressedLeadingZeros(t *testing.T) { // This key is carefully selected to create an X value with 0x00 as the first byte. key, _ := hex.DecodeString( "62e64ee507fedb901b5f2010f039a6a872c6c6eaaf41108f34141f7b1d24f7dd") x, y := bitelliptic.S256().ScalarBaseMult(key) // The expected X is 31 bytes, missing its leading 0x00 byte. expectedX, _ := hex.DecodeString( "f3cfae3aa223e058cfb4e139035191616e60443521baaaa541e08247a5208a") if !bytes.Equal(x.Bytes(), expectedX) { t.Errorf("Didn't get expected X: got %x, expected %x.", x.Bytes(), expectedX) } data := SerializeCompact(point{x, y}) p := ParseCompact(data) if x.Cmp(p.x) != 0 { t.Errorf("X changed: got %v, expected %v.", p.x, x) } if y.Cmp(p.y) != 0 { t.Errorf("Y changed: got %v, expected %v.", p.y, y) } }
func ParseCompact(b []byte) point { if len(b) != 33 { panic(fmt.Sprintf("Data \"%x\" isn't 33 bytes.", b)) } curve := bitelliptic.S256() // y = sqrt(x^3 + B) mod P x := new(big.Int).SetBytes(b[1:33]) x3 := new(big.Int).Mul(x, x) x3.Mul(x3, x) y2 := new(big.Int).Add(x3, curve.B) y2.Mod(y2, curve.P) // sqrt(a) = a^((P+1)/4) e := big.NewInt(1) e = e.Add(e, curve.P) e = e.Div(e, big.NewInt(4)) y := y2.Exp(y2, e, curve.P) switch b[0] { case 0x02: // y should be even. if y.Bit(0) == 1 { y = y.Sub(curve.P, y) } case 0x03: // y should be odd. if y.Bit(0) == 0 { y = y.Sub(curve.P, y) } default: // TODO consider panicking if functions is private. return point{} } return point{x, y} }
func keyIsValid(i *big.Int) bool { if i.Sign() != 0 && i.Cmp(bitelliptic.S256().N) < 0 { return true } return false }
func addInts(a, b *big.Int) *big.Int { i := a.Add(a, b) i.Mod(i, bitelliptic.S256().N) return i }
func addPoints(a, b point) point { x, y := bitelliptic.S256().Add(a.x, a.y, b.x, b.y) return point{x, y} }
func privateToPublic(d *big.Int) point { key := bitecdsa.NewKeyFromInt(bitelliptic.S256(), d) return point{key.X, key.Y} }