Skip to content

Commit f04741e

Browse files
author
Volodymyr Paprotski
committed
KeyDerive should accept ECC Public Key
This changeset extends the KeyDrive() function so that it also supports ECDSA Public Key "re-randomization". Added unit-tests to cover and verify the various cases. Change-Id: Ib48f6b34d928b5f79e9ac670829e5fe6273a2df1 Signed-off-by: Volodymyr Paprotski <[email protected]>
1 parent 75a4c82 commit f04741e

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

bccsp/sw/impl.go

+56-1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,61 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e
226226

227227
// Derive key
228228
switch k.(type) {
229+
case *ecdsaPublicKey:
230+
// Validate opts
231+
if opts == nil {
232+
return nil, errors.New("Invalid Opts parameter. It must not be nil.")
233+
}
234+
235+
ecdsaK := k.(*ecdsaPublicKey)
236+
237+
switch opts.(type) {
238+
239+
// Re-randomized an ECDSA private key
240+
case *bccsp.ECDSAReRandKeyOpts:
241+
reRandOpts := opts.(*bccsp.ECDSAReRandKeyOpts)
242+
tempSK := &ecdsa.PublicKey{
243+
Curve: ecdsaK.pubKey.Curve,
244+
X: new(big.Int),
245+
Y: new(big.Int),
246+
}
247+
248+
var k = new(big.Int).SetBytes(reRandOpts.ExpansionValue())
249+
var one = new(big.Int).SetInt64(1)
250+
n := new(big.Int).Sub(ecdsaK.pubKey.Params().N, one)
251+
k.Mod(k, n)
252+
k.Add(k, one)
253+
254+
// Compute temporary public key
255+
tempX, tempY := ecdsaK.pubKey.ScalarBaseMult(k.Bytes())
256+
tempSK.X, tempSK.Y = tempSK.Add(
257+
ecdsaK.pubKey.X, ecdsaK.pubKey.Y,
258+
tempX, tempY,
259+
)
260+
261+
// Verify temporary public key is a valid point on the reference curve
262+
isOn := tempSK.Curve.IsOnCurve(tempSK.X, tempSK.Y)
263+
if !isOn {
264+
return nil, errors.New("Failed temporary public key IsOnCurve check.")
265+
}
266+
267+
reRandomizedKey := &ecdsaPublicKey{tempSK}
268+
269+
// If the key is not Ephemeral, store it.
270+
if !opts.Ephemeral() {
271+
// Store the key
272+
err = csp.ks.StoreKey(reRandomizedKey)
273+
if err != nil {
274+
return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err)
275+
}
276+
}
277+
278+
return reRandomizedKey, nil
279+
280+
default:
281+
return nil, fmt.Errorf("Unrecognized KeyDerivOpts provided [%s]", opts.Algorithm())
282+
283+
}
229284
case *ecdsaPrivateKey:
230285
// Validate opts
231286
if opts == nil {
@@ -268,7 +323,7 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e
268323
// Verify temporary public key is a valid point on the reference curve
269324
isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y)
270325
if !isOn {
271-
return nil, errors.New("Failed temporary public key IsOnCurve check. This is an foreign key.")
326+
return nil, errors.New("Failed temporary public key IsOnCurve check.")
272327
}
273328

274329
reRandomizedKey := &ecdsaPrivateKey{tempSK}

bccsp/sw/impl_test.go

+27-3
Original file line numberDiff line numberDiff line change
@@ -589,20 +589,44 @@ func TestECDSAKeyReRand(t *testing.T) {
589589
if err != nil {
590590
t.Fatalf("Failed generating ECDSA key [%s]", err)
591591
}
592+
if k == nil {
593+
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key must be different from nil")
594+
}
592595

593596
reRandomizedKey, err := currentBCCSP.KeyDeriv(k, &bccsp.ECDSAReRandKeyOpts{Temporary: false, Expansion: []byte{1}})
594597
if err != nil {
595598
t.Fatalf("Failed re-randomizing ECDSA key [%s]", err)
596599
}
597-
if k == nil {
598-
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key must be different from nil")
599-
}
600600
if !reRandomizedKey.Private() {
601601
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key should be private")
602602
}
603603
if reRandomizedKey.Symmetric() {
604604
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key should be asymmetric")
605605
}
606+
607+
k2, err := k.PublicKey()
608+
if err != nil {
609+
t.Fatalf("Failed getting public ECDSA key from private [%s]", err)
610+
}
611+
if k2 == nil {
612+
t.Fatal("Failed re-randomizing ECDSA key. Re-randomized Key must be different from nil")
613+
}
614+
615+
reRandomizedKey2, err := currentBCCSP.KeyDeriv(k2, &bccsp.ECDSAReRandKeyOpts{Temporary: false, Expansion: []byte{1}})
616+
if err != nil {
617+
t.Fatalf("Failed re-randomizing ECDSA key [%s]", err)
618+
}
619+
620+
if reRandomizedKey2.Private() {
621+
t.Fatal("Re-randomized public Key must remain public")
622+
}
623+
if reRandomizedKey2.Symmetric() {
624+
t.Fatal("Re-randomized ECDSA asymmetric key must remain asymmetric")
625+
}
626+
627+
if false == bytes.Equal(reRandomizedKey.SKI(), reRandomizedKey2.SKI()) {
628+
t.Fatal("Re-randomized ECDSA Private- or Public-Keys must end up having the same SKI")
629+
}
606630
}
607631

608632
func TestECDSASign(t *testing.T) {

0 commit comments

Comments
 (0)