Skip to content

Commit 3e6db0f

Browse files
author
nauman
committed
ecdsa lib
1 parent c9f5b90 commit 3e6db0f

File tree

5 files changed

+558
-0
lines changed

5 files changed

+558
-0
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "sseclient"]
22
path = sseclient
33
url = ./sseclient
4+
[submodule "bitcoin-crypto"]
5+
path = bitcoin-crypto
6+
url = ./bitcoin-crypto

bitcoin-crypto/LICENSE

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright (c) 2009 The Go Authors. All rights reserved.
2+
Copyright (c) 2011 ThePiachu. All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are
6+
met:
7+
8+
* Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
* Redistributions in binary form must reproduce the above
11+
copyright notice, this list of conditions and the following disclaimer
12+
in the documentation and/or other materials provided with the
13+
distribution.
14+
* Neither the name of Google Inc. nor the names of its
15+
contributors may be used to endorse or promote products derived from
16+
this software without specific prior written permission.
17+
* The name of ThePiachu may not be used to endorse or promote products
18+
derived from this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

bitcoin-crypto/README

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
This is a modified ECDSA library for Google Go language.
2+
It is based on original code created by The Go Authors, modified to handle Koblitz curves (such as secp256k1 that is commonly used by Bitcoin applications).
3+
4+
For more information on Koblitz curves, check out this link:
5+
http://www.secg.org/collateral/sec2_final.pdf
6+
7+
For more information on Bitcoins, check out this link:
8+
http://bitcoin.org/
9+
10+
Code status:
11+
-The code is a beta version, it should work correctly, but it has not yet been thoroughly tested.
12+
13+
TODO:
14+
-Add more test cases
15+
-Verify library's proper functionality on sample curves
16+
-Test library in an actual application
17+
-Verify copyright notices and other comments in the code
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Copyright 2011 The Go Authors. All rights reserved.
2+
// Copyright 2011 ThePiachu. All rights reserved.
3+
// Use of this source code is governed by a BSD-style
4+
// license that can be found in the LICENSE file.
5+
6+
// Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
7+
// defined in FIPS 186-3.
8+
package bitecdsa
9+
10+
// References:
11+
// [NSA]: Suite B implementor's guide to FIPS 186-3,
12+
// http://www.nsa.gov/ia/_files/ecdsa.pdf
13+
// [SECG]: SECG, SEC1
14+
// http://www.secg.org/download/aid-780/sec1-v2.pdf
15+
16+
import (
17+
"io"
18+
"math/big"
19+
20+
"../bitelliptic"
21+
)
22+
23+
// PublicKey represents an ECDSA public key.
24+
type PublicKey struct {
25+
*bitelliptic.BitCurve
26+
X, Y *big.Int
27+
}
28+
29+
// PrivateKey represents a ECDSA private key.
30+
type PrivateKey struct {
31+
PublicKey
32+
D *big.Int
33+
}
34+
35+
var one = new(big.Int).SetInt64(1)
36+
37+
// randFieldElement returns a random element of the field underlying the given
38+
// curve using the procedure given in [NSA] A.2.1.
39+
func randFieldElement(c *bitelliptic.BitCurve, rand io.Reader) (k *big.Int, err error) {
40+
b := make([]byte, c.BitSize/8+8)
41+
_, err = io.ReadFull(rand, b)
42+
if err != nil {
43+
return
44+
}
45+
46+
k = new(big.Int).SetBytes(b)
47+
n := new(big.Int).Sub(c.N, one)
48+
k.Mod(k, n)
49+
k.Add(k, one)
50+
return
51+
}
52+
53+
// GenerateKey generates a public&private key pair.
54+
func GenerateKey(c *bitelliptic.BitCurve, rand io.Reader) (priv *PrivateKey, err error) {
55+
k, err := randFieldElement(c, rand)
56+
if err != nil {
57+
return
58+
}
59+
60+
priv = new(PrivateKey)
61+
priv.PublicKey.BitCurve = c
62+
priv.D = k
63+
priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
64+
return
65+
}
66+
67+
// hashToInt converts a hash value to an integer. There is some disagreement
68+
// about how this is done. [NSA] suggests that this is done in the obvious
69+
// manner, but [SECG] truncates the hash to the bit-length of the curve order
70+
// first. We follow [SECG] because that's what OpenSSL does.
71+
func hashToInt(hash []byte, c *bitelliptic.BitCurve) *big.Int {
72+
orderBits := c.N.BitLen()
73+
orderBytes := (orderBits + 7) / 8
74+
if len(hash) > orderBytes {
75+
hash = hash[:orderBytes]
76+
}
77+
78+
ret := new(big.Int).SetBytes(hash)
79+
excess := orderBytes*8 - orderBits
80+
if excess > 0 {
81+
ret.Rsh(ret, uint(excess))
82+
}
83+
return ret
84+
}
85+
86+
// Sign signs an arbitrary length hash (which should be the result of hashing a
87+
// larger message) using the private key, priv. It returns the signature as a
88+
// pair of integers. The security of the private key depends on the entropy of
89+
// rand.
90+
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
91+
// See [NSA] 3.4.1
92+
c := priv.PublicKey.BitCurve
93+
94+
var k, kInv *big.Int
95+
for {
96+
for {
97+
k, err = randFieldElement(c, rand)
98+
if err != nil {
99+
r = nil
100+
return
101+
}
102+
103+
kInv = new(big.Int).ModInverse(k, c.N)
104+
r, _ = priv.BitCurve.ScalarBaseMult(k.Bytes())
105+
r.Mod(r, priv.BitCurve.N)
106+
if r.Sign() != 0 {
107+
break
108+
}
109+
}
110+
111+
e := hashToInt(hash, c)
112+
s = new(big.Int).Mul(priv.D, r)
113+
s.Add(s, e)
114+
s.Mul(s, kInv)
115+
s.Mod(s, priv.PublicKey.BitCurve.N)
116+
if s.Sign() != 0 {
117+
break
118+
}
119+
}
120+
121+
return
122+
}
123+
124+
// Verify verifies the signature in r, s of hash using the public key, pub. It
125+
// returns true iff the signature is valid.
126+
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
127+
// See [NSA] 3.4.2
128+
c := pub.BitCurve
129+
130+
if r.Sign() == 0 || s.Sign() == 0 {
131+
return false
132+
}
133+
if r.Cmp(c.N) >= 0 || s.Cmp(c.N) >= 0 {
134+
return false
135+
}
136+
e := hashToInt(hash, c)
137+
w := new(big.Int).ModInverse(s, c.N)
138+
139+
u1 := e.Mul(e, w)
140+
u2 := w.Mul(r, w)
141+
142+
x1, y1 := c.ScalarBaseMult(u1.Bytes())
143+
x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
144+
if x1.Cmp(x2) == 0 {
145+
return false
146+
}
147+
x, _ := c.Add(x1, y1, x2, y2)
148+
x.Mod(x, c.N)
149+
return x.Cmp(r) == 0
150+
}

0 commit comments

Comments
 (0)