_, err := hasher.Write(data)
dgst := hasher.Sum(nil)
curve := gost3410.CurveIdtc26gost34102012256paramSetB()
- prvRaw := make([]byte, int(gost3410.Mode2001))
+ prvRaw := make([]byte, int(32))
_, err = io.ReadFull(rand.Reader, prvRaw)
- prv, err := gost3410.NewPrivateKey(curve, gost3410.Mode2001, prvRaw)
+ prv, err := gost3410.NewPrivateKey(curve, prvRaw)
pub, err := prv.PublicKey()
pubRaw := pub.Raw()
sign, err := prv.Sign(rand.Reader, dgst, nil)
- pub, err = gost3410.NewPublicKey(curve, gost3410.Mode2001, pubRaw)
+ pub, err = gost3410.NewPublicKey(curve, pubRaw)
isValid, err := pub.VerifyDigest(dgst, sign)
if !isValid { panic("signature is invalid") }
}
}
c := CurveIdGostR34102001TestParamSet()
- prv, err := NewPrivateKey(c, Mode2001, priv)
+ prv, err := NewPrivateKey(c, priv)
if err != nil {
t.FailNow()
}
func TestRandom2001(t *testing.T) {
c := CurveIdGostR34102001TestParamSet()
f := func(data [31]byte, digest [32]byte) bool {
- prv, err := NewPrivateKey(
- c,
- Mode2001,
- append([]byte{0xde}, data[:]...),
- )
+ prv, err := NewPrivateKey(c, append([]byte{0xde}, data[:]...))
if err != nil {
return false
}
return false
}
pubRaw := pub.Raw()
- pub, err = NewPublicKey(c, Mode2001, pubRaw)
+ pub, err = NewPublicKey(c, pubRaw)
if err != nil {
return false
}
func BenchmarkSign2001(b *testing.B) {
c := CurveIdGostR34102001TestParamSet()
- prv, err := GenPrivateKey(c, Mode2001, rand.Reader)
+ prv, err := GenPrivateKey(c, rand.Reader)
if err != nil {
b.FailNow()
}
func BenchmarkVerify2001(b *testing.B) {
c := CurveIdGostR34102001TestParamSet()
- prv, err := GenPrivateKey(c, Mode2001, rand.Reader)
+ prv, err := GenPrivateKey(c, rand.Reader)
if err != nil {
b.FailNow()
}
func TestPrvEqualsTo1(t *testing.T) {
c := CurveIdGostR34102001TestParamSet()
- prvRaw := make([]byte, int(Mode2001))
+ prvRaw := make([]byte, 32)
prvRaw[len(prvRaw)-1] = 1
- prv, err := NewPrivateKey(c, Mode2001, prvRaw)
+ prv, err := NewPrivateKey(c, prvRaw)
if err != nil {
t.FailNow()
}
0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40,
}
reverse(prvRaw)
- prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), Mode2001, prvRaw)
+ prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), prvRaw)
if err != nil {
t.FailNow()
}
0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A,
}
reverse(prvRaw)
- prv, err := NewPrivateKey(c, Mode2012, prvRaw)
+ prv, err := NewPrivateKey(c, prvRaw)
if err != nil {
t.FailNow()
}
if err != nil {
t.FailNow()
}
- prv, err := NewPrivateKey(c, Mode2012, priv)
+ prv, err := NewPrivateKey(c, priv)
if err != nil {
t.FailNow()
}
func TestRandom2012(t *testing.T) {
c := CurveIdtc26gost341012512paramSetA()
f := func(prvRaw [64 - 1]byte, digest [64]byte) bool {
- prv, err := NewPrivateKey(
- c,
- Mode2012,
- append([]byte{0xde}, prvRaw[:]...),
- )
+ prv, err := NewPrivateKey(c, append([]byte{0xde}, prvRaw[:]...))
if err != nil {
return false
}
return false
}
pubRaw := pub.Raw()
- pub, err = NewPublicKey(c, Mode2012, pubRaw)
+ pub, err = NewPublicKey(c, pubRaw)
if err != nil {
return false
}
func BenchmarkSign2012(b *testing.B) {
c := CurveIdtc26gost341012512paramSetA()
- prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
+ prv, err := GenPrivateKey(c, rand.Reader)
if err != nil {
b.FailNow()
}
func BenchmarkVerify2012(b *testing.B) {
c := CurveIdtc26gost341012512paramSetA()
- prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
+ prv, err := GenPrivateKey(c, rand.Reader)
if err != nil {
b.FailNow()
}
return &c, nil
}
+func (c *Curve) PointSize() int {
+ return PointSize(c.P)
+}
+
func (c *Curve) pos(v *big.Int) {
if v.Cmp(zero) < 0 {
v.Add(v, c.P)
package gost3410
-type Mode int
-
var (
- Mode2001 Mode = Mode(32)
- Mode2012 Mode = Mode(64)
-
CurveGostR34102001ParamSetcc func() *Curve = func() *Curve {
curve, err := NewCurve(
bytes2big([]byte{
)
type PrivateKey struct {
- C *Curve
- Mode Mode
- Key *big.Int
+ C *Curve
+ Key *big.Int
}
-func NewPrivateKey(curve *Curve, mode Mode, raw []byte) (*PrivateKey, error) {
- if len(raw) != int(mode) {
- return nil, fmt.Errorf("gogost/gost3410: len(key) != %d", mode)
+func NewPrivateKey(curve *Curve, raw []byte) (*PrivateKey, error) {
+ pointSize := curve.PointSize()
+ if len(raw) != pointSize {
+ return nil, fmt.Errorf("gogost/gost3410: len(key) != %d", pointSize)
}
- key := make([]byte, int(mode))
+ key := make([]byte, pointSize)
for i := 0; i < len(key); i++ {
key[i] = raw[len(raw)-i-1]
}
if k.Cmp(zero) == 0 {
return nil, errors.New("gogost/gost3410: zero private key")
}
- return &PrivateKey{curve, mode, k}, nil
+ return &PrivateKey{curve, k}, nil
}
-func GenPrivateKey(curve *Curve, mode Mode, rand io.Reader) (*PrivateKey, error) {
- raw := make([]byte, int(mode))
+func GenPrivateKey(curve *Curve, rand io.Reader) (*PrivateKey, error) {
+ raw := make([]byte, curve.PointSize())
if _, err := io.ReadFull(rand, raw); err != nil {
return nil, err
}
- return NewPrivateKey(curve, mode, raw)
+ return NewPrivateKey(curve, raw)
}
func (prv *PrivateKey) Raw() []byte {
- raw := pad(prv.Key.Bytes(), int(prv.Mode))
+ raw := pad(prv.Key.Bytes(), prv.C.PointSize())
reverse(raw)
return raw
}
if err != nil {
return nil, err
}
- return &PublicKey{prv.C, prv.Mode, x, y}, nil
+ return &PublicKey{prv.C, x, y}, nil
}
func (prv *PrivateKey) SignDigest(digest []byte, rand io.Reader) ([]byte, error) {
if e.Cmp(zero) == 0 {
e = big.NewInt(1)
}
- kRaw := make([]byte, int(prv.Mode))
+ kRaw := make([]byte, prv.C.PointSize())
var err error
var k *big.Int
var r *big.Int
if s.Cmp(zero) == 0 {
goto Retry
}
+ pointSize := prv.C.PointSize()
return append(
- pad(s.Bytes(), int(prv.Mode)),
- pad(r.Bytes(), int(prv.Mode))...,
+ pad(s.Bytes(), pointSize),
+ pad(r.Bytes(), pointSize)...,
), nil
}
)
func TestSignerInterface(t *testing.T) {
- prvRaw := make([]byte, int(Mode2001))
+ prvRaw := make([]byte, 32)
rand.Read(prvRaw)
- prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), Mode2001, prvRaw)
+ prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), prvRaw)
if err != nil {
t.FailNow()
}
)
type PublicKey struct {
- C *Curve
- Mode Mode
- X *big.Int
- Y *big.Int
+ C *Curve
+ X *big.Int
+ Y *big.Int
}
-func NewPublicKey(curve *Curve, mode Mode, raw []byte) (*PublicKey, error) {
- key := make([]byte, 2*int(mode))
+func NewPublicKey(curve *Curve, raw []byte) (*PublicKey, error) {
+ pointSize := curve.PointSize()
+ key := make([]byte, 2*pointSize)
if len(raw) != len(key) {
return nil, fmt.Errorf("gogost/gost3410: len(key) != %d", len(key))
}
}
return &PublicKey{
curve,
- mode,
- bytes2big(key[int(mode) : 2*int(mode)]),
- bytes2big(key[:int(mode)]),
+ bytes2big(key[pointSize : 2*pointSize]),
+ bytes2big(key[:pointSize]),
}, nil
}
func (pub *PublicKey) Raw() []byte {
+ pointSize := pub.C.PointSize()
raw := append(
- pad(pub.Y.Bytes(), int(pub.Mode)),
- pad(pub.X.Bytes(), int(pub.Mode))...,
+ pad(pub.Y.Bytes(), pointSize),
+ pad(pub.X.Bytes(), pointSize)...,
)
reverse(raw)
return raw
}
func (pub *PublicKey) VerifyDigest(digest, signature []byte) (bool, error) {
- if len(signature) != 2*int(pub.Mode) {
- return false, fmt.Errorf("gogost/gost3410: len(signature) != %d", 2*int(pub.Mode))
+ pointSize := pub.C.PointSize()
+ if len(signature) != 2*pointSize {
+ return false, fmt.Errorf("gogost/gost3410: len(signature) != %d", 2*pointSize)
}
- s := bytes2big(signature[:pub.Mode])
- r := bytes2big(signature[pub.Mode:])
+ s := bytes2big(signature[:pointSize])
+ r := bytes2big(signature[pointSize:])
if r.Cmp(zero) <= 0 ||
r.Cmp(pub.C.Q) >= 0 ||
s.Cmp(zero) <= 0 ||
func pad(d []byte, size int) []byte {
return append(make([]byte, size-len(d)), d...)
}
+
+func PointSize(p *big.Int) int {
+ if p.BitLen() > 256 {
+ return 64
+ }
+ return 32
+}
return nil, err
}
}
- pk := PublicKey{prv.C, prv.Mode, keyX, keyY}
+ pk := PublicKey{prv.C, keyX, keyY}
return pk.Raw(), nil
}
// RFC 4357 VKO GOST R 34.10-2001 key agreement function.
// UKM is user keying material, also called VKO-factor.
func (prv *PrivateKey) KEK2001(pub *PublicKey, ukm *big.Int) ([]byte, error) {
- if prv.Mode != Mode2001 {
- return nil, errors.New("gogost/gost3410: KEK2001 can not be used in Mode2012")
+ if prv.C.PointSize() != 32 {
+ return nil, errors.New("gogost/gost3410: KEK2001 is only for 256-bit curves")
}
key, err := prv.KEK(pub, ukm)
if err != nil {
prvRaw1, _ := hex.DecodeString("1df129e43dab345b68f6a852f4162dc69f36b2f84717d08755cc5c44150bf928")
prvRaw2, _ := hex.DecodeString("5b9356c6474f913f1e83885ea0edd5df1a43fd9d799d219093241157ac9ed473")
kek, _ := hex.DecodeString("ee4618a0dbb10cb31777b4b86a53d9e7ef6cb3e400101410f0c0f2af46c494a6")
- prv1, _ := NewPrivateKey(c, Mode2001, prvRaw1)
- prv2, _ := NewPrivateKey(c, Mode2001, prvRaw2)
+ prv1, _ := NewPrivateKey(c, prvRaw1)
+ prv2, _ := NewPrivateKey(c, prvRaw2)
pub1, _ := prv1.PublicKey()
pub2, _ := prv2.PublicKey()
kek1, _ := prv1.KEK2001(pub2, ukm)
func TestRandomVKO2001(t *testing.T) {
c := CurveIdGostR34102001TestParamSet()
f := func(prvRaw1 [32]byte, prvRaw2 [32]byte, ukmRaw [8]byte) bool {
- prv1, err := NewPrivateKey(c, Mode2001, prvRaw1[:])
+ prv1, err := NewPrivateKey(c, prvRaw1[:])
if err != nil {
return false
}
- prv2, err := NewPrivateKey(c, Mode2001, prvRaw2[:])
+ prv2, err := NewPrivateKey(c, prvRaw2[:])
if err != nil {
return false
}
pubRawA, _ := hex.DecodeString("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")
prvRawB, _ := hex.DecodeString("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")
pubRawB, _ := hex.DecodeString("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")
- pubA, _ := NewPublicKey(c, Mode2012, pubRawA)
- pubB, _ := NewPublicKey(c, Mode2012, pubRawB)
+ pubA, _ := NewPublicKey(c, pubRawA)
+ pubB, _ := NewPublicKey(c, pubRawB)
kek, _ := hex.DecodeString("c9a9a77320e2cc559ed72dce6f47e2192ccea95fa648670582c054c0ef36c221")
- prvA, _ := NewPrivateKey(c, Mode2012, prvRawA)
- prvB, _ := NewPrivateKey(c, Mode2012, prvRawB)
+ prvA, _ := NewPrivateKey(c, prvRawA)
+ prvB, _ := NewPrivateKey(c, prvRawB)
kekA, _ := prvA.KEK2012256(pubB, ukm)
kekB, _ := prvB.KEK2012256(pubA, ukm)
if bytes.Compare(kekA, kekB) != 0 {
func TestRandomVKO2012256(t *testing.T) {
c := CurveIdtc26gost341012512paramSetA()
f := func(prvRaw1 [64]byte, prvRaw2 [64]byte, ukmRaw [8]byte) bool {
- prv1, err := NewPrivateKey(c, Mode2012, prvRaw1[:])
+ prv1, err := NewPrivateKey(c, prvRaw1[:])
if err != nil {
return false
}
- prv2, err := NewPrivateKey(c, Mode2012, prvRaw2[:])
+ prv2, err := NewPrivateKey(c, prvRaw2[:])
if err != nil {
return false
}
pubRawA, _ := hex.DecodeString("aab0eda4abff21208d18799fb9a8556654ba783070eba10cb9abb253ec56dcf5d3ccba6192e464e6e5bcb6dea137792f2431f6c897eb1b3c0cc14327b1adc0a7914613a3074e363aedb204d38d3563971bd8758e878c9db11403721b48002d38461f92472d40ea92f9958c0ffa4c93756401b97f89fdbe0b5e46e4a4631cdb5a")
prvRawB, _ := hex.DecodeString("48c859f7b6f11585887cc05ec6ef1390cfea739b1a18c0d4662293ef63b79e3b8014070b44918590b4b996acfea4edfbbbcccc8c06edd8bf5bda92a51392d0db")
pubRawB, _ := hex.DecodeString("192fe183b9713a077253c72c8735de2ea42a3dbc66ea317838b65fa32523cd5efca974eda7c863f4954d1147f1f2b25c395fce1c129175e876d132e94ed5a65104883b414c9b592ec4dc84826f07d0b6d9006dda176ce48c391e3f97d102e03bb598bf132a228a45f7201aba08fc524a2d77e43a362ab022ad4028f75bde3b79")
- pubA, _ := NewPublicKey(c, Mode2012, pubRawA)
- pubB, _ := NewPublicKey(c, Mode2012, pubRawB)
+ pubA, _ := NewPublicKey(c, pubRawA)
+ pubB, _ := NewPublicKey(c, pubRawB)
kek, _ := hex.DecodeString("79f002a96940ce7bde3259a52e015297adaad84597a0d205b50e3e1719f97bfa7ee1d2661fa9979a5aa235b558a7e6d9f88f982dd63fc35a8ec0dd5e242d3bdf")
- prvA, _ := NewPrivateKey(c, Mode2012, prvRawA)
- prvB, _ := NewPrivateKey(c, Mode2012, prvRawB)
+ prvA, _ := NewPrivateKey(c, prvRawA)
+ prvB, _ := NewPrivateKey(c, prvRawB)
kekA, _ := prvA.KEK2012512(pubB, ukm)
kekB, _ := prvB.KEK2012512(pubA, ukm)
if bytes.Compare(kekA, kekB) != 0 {
func TestRandomVKO2012512(t *testing.T) {
c := CurveIdtc26gost341012512paramSetA()
f := func(prvRaw1 [64]byte, prvRaw2 [64]byte, ukmRaw [8]byte) bool {
- prv1, err := NewPrivateKey(c, Mode2012, prvRaw1[:])
+ prv1, err := NewPrivateKey(c, prvRaw1[:])
if err != nil {
return false
}
- prv2, err := NewPrivateKey(c, Mode2012, prvRaw2[:])
+ prv2, err := NewPrivateKey(c, prvRaw2[:])
if err != nil {
return false
}
@node Download
@unnumbered Download
-@set VERSION 4.3.1
+@set VERSION 5.0.0
Preferable way is to download tarball with the signature from
website and, for example, run tests with benchmarks:
@table @strong
+@anchor{Release 5.0.0}
+@item 5.0.0
+ Backward incompatible remove of excess misleading @code{gost3410.Mode}
+ from all related functions. Point/key sizes are determined by
+ looking at curve's parameters size.
+
@anchor{Release 4.3.0}
@item 4.3.0
@strong{Fixed} nasty bug with Edwards curves using in 34.10-VKO
_, err := hasher.Write(data)
dgst := hasher.Sum(nil)
curve := gost3410.CurveIdtc26gost34102012256paramSetB()
- prvRaw := make([]byte, int(gost3410.Mode2001))
+ prvRaw := make([]byte, 32)
_, err = io.ReadFull(rand.Reader, prvRaw)
- prv, err := gost3410.NewPrivateKey(curve, gost3410.Mode2001, prvRaw)
+ prv, err := gost3410.NewPrivateKey(curve, prvRaw)
pub, err := prv.PublicKey()
pubRaw := pub.Raw()
sign, err := prv.Sign(rand.Reader, dgst, nil)
- pub, err = gost3410.NewPublicKey(curve, gost3410.Mode2001, pubRaw)
+ pub, err = gost3410.NewPublicKey(curve, pubRaw)
isValid, err := pub.VerifyDigest(dgst, sign)
if !isValid { panic("signature is invalid") }
}