github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/bccsp/sw/ecdsa.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 package sw 17 18 import ( 19 "crypto/ecdsa" 20 "crypto/elliptic" 21 "crypto/rand" 22 "encoding/asn1" 23 "errors" 24 "fmt" 25 "math/big" 26 27 "github.com/hyperledger/fabric/bccsp" 28 ) 29 30 type ECDSASignature struct { 31 R, S *big.Int 32 } 33 34 var ( 35 // curveHalfOrders contains the precomputed curve group orders halved. 36 // It is used to ensure that signature' S value is lower or equal to the 37 // curve group order halved. We accept only low-S signatures. 38 // They are precomputed for efficiency reasons. 39 curveHalfOrders map[elliptic.Curve]*big.Int = map[elliptic.Curve]*big.Int{ 40 elliptic.P224(): new(big.Int).Rsh(elliptic.P224().Params().N, 1), 41 elliptic.P256(): new(big.Int).Rsh(elliptic.P256().Params().N, 1), 42 elliptic.P384(): new(big.Int).Rsh(elliptic.P384().Params().N, 1), 43 elliptic.P521(): new(big.Int).Rsh(elliptic.P521().Params().N, 1), 44 } 45 ) 46 47 func MarshalECDSASignature(r, s *big.Int) ([]byte, error) { 48 return asn1.Marshal(ECDSASignature{r, s}) 49 } 50 51 func UnmarshalECDSASignature(raw []byte) (*big.Int, *big.Int, error) { 52 // Unmarshal 53 sig := new(ECDSASignature) 54 _, err := asn1.Unmarshal(raw, sig) 55 if err != nil { 56 return nil, nil, fmt.Errorf("Failed unmashalling signature [%s]", err) 57 } 58 59 // Validate sig 60 if sig.R == nil { 61 return nil, nil, errors.New("Invalid signature. R must be different from nil.") 62 } 63 if sig.S == nil { 64 return nil, nil, errors.New("Invalid signature. S must be different from nil.") 65 } 66 67 if sig.R.Sign() != 1 { 68 return nil, nil, errors.New("Invalid signature. R must be larger than zero") 69 } 70 if sig.S.Sign() != 1 { 71 return nil, nil, errors.New("Invalid signature. S must be larger than zero") 72 } 73 74 return sig.R, sig.S, nil 75 } 76 77 func signECDSA(k *ecdsa.PrivateKey, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { 78 r, s, err := ecdsa.Sign(rand.Reader, k, digest) 79 if err != nil { 80 return nil, err 81 } 82 83 s, _, err = ToLowS(&k.PublicKey, s) 84 if err != nil { 85 return nil, err 86 } 87 88 return MarshalECDSASignature(r, s) 89 } 90 91 func verifyECDSA(k *ecdsa.PublicKey, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { 92 r, s, err := UnmarshalECDSASignature(signature) 93 if err != nil { 94 return false, fmt.Errorf("Failed unmashalling signature [%s]", err) 95 } 96 97 lowS, err := IsLowS(k, s) 98 if err != nil { 99 return false, err 100 } 101 102 if !lowS { 103 return false, fmt.Errorf("Invalid S. Must be smaller than half the order [%s][%s].", s, curveHalfOrders[k.Curve]) 104 } 105 106 return ecdsa.Verify(k, digest, r, s), nil 107 } 108 109 func SignatureToLowS(k *ecdsa.PublicKey, signature []byte) ([]byte, error) { 110 r, s, err := UnmarshalECDSASignature(signature) 111 if err != nil { 112 return nil, err 113 } 114 115 s, modified, err := ToLowS(k, s) 116 if err != nil { 117 return nil, err 118 } 119 120 if modified { 121 return MarshalECDSASignature(r, s) 122 } 123 124 return signature, nil 125 } 126 127 // IsLow checks that s is a low-S 128 func IsLowS(k *ecdsa.PublicKey, s *big.Int) (bool, error) { 129 halfOrder, ok := curveHalfOrders[k.Curve] 130 if !ok { 131 return false, fmt.Errorf("Curve not recognized [%s]", k.Curve) 132 } 133 134 return s.Cmp(halfOrder) != 1, nil 135 136 } 137 138 func ToLowS(k *ecdsa.PublicKey, s *big.Int) (*big.Int, bool, error) { 139 lowS, err := IsLowS(k, s) 140 if err != nil { 141 return nil, false, err 142 } 143 144 if !lowS { 145 // Set s to N - s that will be then in the lower part of signature space 146 // less or equal to half order 147 s.Sub(k.Params().N, s) 148 149 return s, true, nil 150 } 151 152 return s, false, nil 153 } 154 155 type ecdsaSigner struct{} 156 157 func (s *ecdsaSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { 158 return signECDSA(k.(*ecdsaPrivateKey).privKey, digest, opts) 159 } 160 161 type ecdsaPrivateKeyVerifier struct{} 162 163 func (v *ecdsaPrivateKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { 164 return verifyECDSA(&(k.(*ecdsaPrivateKey).privKey.PublicKey), signature, digest, opts) 165 } 166 167 type ecdsaPublicKeyKeyVerifier struct{} 168 169 func (v *ecdsaPublicKeyKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { 170 return verifyECDSA(k.(*ecdsaPublicKey).pubKey, signature, digest, opts) 171 }