OSDN Git Service

Wallet store test (#312)
[bytom/vapor.git] / vendor / github.com / tendermint / ed25519 / ed25519.go
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package ed25519 implements the Ed25519 signature algorithm. See
6 // http://ed25519.cr.yp.to/.
7 package ed25519
8
9 // This code is a port of the public domain, "ref10" implementation of ed25519
10 // from SUPERCOP.
11
12 import (
13         "crypto/sha512"
14         "crypto/subtle"
15
16         "github.com/tendermint/ed25519/edwards25519"
17 )
18
19 const (
20         PublicKeySize  = 32
21         PrivateKeySize = 64
22         SignatureSize  = 64
23 )
24
25 // MakePublicKey makes a publicKey from the first half of privateKey.
26 func MakePublicKey(privateKey *[PrivateKeySize]byte) (publicKey *[PublicKeySize]byte) {
27         publicKey = new([32]byte)
28
29         h := sha512.New()
30         h.Write(privateKey[:32])
31         digest := h.Sum(nil)
32
33         digest[0] &= 248
34         digest[31] &= 127
35         digest[31] |= 64
36
37         var A edwards25519.ExtendedGroupElement
38         var hBytes [32]byte
39         copy(hBytes[:], digest)
40         edwards25519.GeScalarMultBase(&A, &hBytes)
41         A.ToBytes(publicKey)
42
43         copy(privateKey[32:], publicKey[:])
44         return
45 }
46
47 // Sign signs the message with privateKey and returns a signature.
48 func Sign(privateKey *[PrivateKeySize]byte, message []byte) *[SignatureSize]byte {
49         h := sha512.New()
50         h.Write(privateKey[:32])
51
52         var digest1, messageDigest, hramDigest [64]byte
53         var expandedSecretKey [32]byte
54         h.Sum(digest1[:0])
55         copy(expandedSecretKey[:], digest1[:])
56         expandedSecretKey[0] &= 248
57         expandedSecretKey[31] &= 63
58         expandedSecretKey[31] |= 64
59
60         h.Reset()
61         h.Write(digest1[32:])
62         h.Write(message)
63         h.Sum(messageDigest[:0])
64
65         var messageDigestReduced [32]byte
66         edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
67         var R edwards25519.ExtendedGroupElement
68         edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
69
70         var encodedR [32]byte
71         R.ToBytes(&encodedR)
72
73         h.Reset()
74         h.Write(encodedR[:])
75         h.Write(privateKey[32:])
76         h.Write(message)
77         h.Sum(hramDigest[:0])
78         var hramDigestReduced [32]byte
79         edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
80
81         var s [32]byte
82         edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
83
84         signature := new([64]byte)
85         copy(signature[:], encodedR[:])
86         copy(signature[32:], s[:])
87         return signature
88 }
89
90 // Verify returns true iff sig is a valid signature of message by publicKey.
91 func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]byte) bool {
92         if sig[63]&224 != 0 {
93                 return false
94         }
95
96         var A edwards25519.ExtendedGroupElement
97         if !A.FromBytes(publicKey) {
98                 return false
99         }
100         edwards25519.FeNeg(&A.X, &A.X)
101         edwards25519.FeNeg(&A.T, &A.T)
102
103         h := sha512.New()
104         h.Write(sig[:32])
105         h.Write(publicKey[:])
106         h.Write(message)
107         var digest [64]byte
108         h.Sum(digest[:0])
109
110         var hReduced [32]byte
111         edwards25519.ScReduce(&hReduced, &digest)
112
113         var R edwards25519.ProjectiveGroupElement
114         var b [32]byte
115         copy(b[:], sig[32:])
116         edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
117
118         var checkR [32]byte
119         R.ToBytes(&checkR)
120         return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1
121 }