Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

draft-irtf-cfrg-vrf-06 #1346

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions core/crypto/draft-irtf-cfrg-vrf-06/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright 2020 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package vrf

import (
"bytes"
"crypto/elliptic"
"math/big"
)

// I2OSP converts a nonnegative integer to an octet string of a specified length.
// RFC8017 section-4.1 (big endian representation)
func I2OSP(x *big.Int, rLen uint) []byte {
// 1. If x >= 256^rLen, output "integer too large" and stop.
one := big.NewInt(1)
if x.Cmp(new(big.Int).Lsh(one, rLen*8)) >= 0 {
panic("integer too large")
}
// 2. Write the integer x in its unique rLen-digit representation in base 256:
// x = x_(rLen-1) 256^(rLen-1) + x_(rLen-2) 256^(rLen-2) + ... + x_1 256 + x_0,
// where 0 <= x_i < 256
// (note that one or more leading digits will be zero if x is less than 256^(rLen-1)).
// 3. Let the octet X_i have the integer value x_(rLen-i) for 1 <= i <= rLen.
// Output the octet string X = X_1 X_2 ... X_rLen.

var b bytes.Buffer
xLen := (uint(x.BitLen()) + 7) >> 3
if rLen > xLen {
b.Write(make([]byte, rLen-xLen)) // prepend 0s
}
b.Write(x.Bytes())
return b.Bytes()[uint(b.Len())-rLen:] // The rightmost rLen bytes.
}

// SECG1EncodeCompressed converts an EC point to an octet string according to
// the encoding specified in Section 2.3.3 of [SECG1] with point compression
// on. This implies ptLen = 2n + 1 = 33.
//
// SECG1 Section 2.3.3 https://www.secg.org/sec1-v1.99.dif.pdf
//
// (Note that certain software implementations do not introduce a separate
// elliptic curve point type and instead directly treat the EC point as an
// octet string per above encoding. When using such an implementation, the
// point_to_string function can be treated as the identity function.)
func SECG1EncodeCompressed(curve elliptic.Curve, x, y *big.Int) []byte {
byteLen := (curve.Params().BitSize + 7) >> 3
ret := make([]byte, 1+byteLen)
ret[0] = 2 // compressed point

xBytes := x.Bytes()
copy(ret[1+byteLen-len(xBytes):], xBytes)
ret[0] += byte(y.Bit(0))
return ret
}

// This file implements compressed point unmarshaling. Preferably this
// functionality would be in a standard library. Code borrowed from:
// https://go-review.googlesource.com/#/c/1883/2/src/crypto/elliptic/elliptic.go

// SECG1Decode decodes a EC point, given as a compressed string.
// If the decoding fails x and y will be nil.
//
// http://www.secg.org/sec1-v2.pdf
// https://tools.ietf.org/html/rfc8032#section-5.1.3
func SECG1Decode(curve elliptic.Curve, data []byte) (x, y *big.Int) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

65-94 lines are duplicate of core/crypto/vrf/p256/unmarshal.go:27-56 (from dupl)

byteLen := (curve.Params().BitSize + 7) >> 3
if (data[0] &^ 1) != 2 {
return // unrecognized point encoding
}
if len(data) != 1+byteLen {
return
}

// Based on Routine 2.2.4 in NIST Mathematical routines paper
params := curve.Params()
tx := new(big.Int).SetBytes(data[1 : 1+byteLen])
y2 := y2(params, tx)
sqrt := defaultSqrt
ty := sqrt(y2, params.P)
if ty == nil {
return // "y^2" is not a square: invalid point
}
var y2c big.Int
y2c.Mul(ty, ty).Mod(&y2c, params.P)
if y2c.Cmp(y2) != 0 {
return // sqrt(y2)^2 != y2: invalid point
}
if ty.Bit(0) != uint(data[0]&1) {
ty.Sub(params.P, ty)
}

x, y = tx, ty // valid point: return it
return
}

// Use the curve equation to calculate y² given x.
// only applies to curves of the form y² = x³ - 3x + b.
func y2(curve *elliptic.CurveParams, x *big.Int) *big.Int {
// y² = x³ - 3x + b
x3 := new(big.Int).Mul(x, x)
x3.Mul(x3, x)

threeX := new(big.Int).Lsh(x, 1)
threeX.Add(threeX, x)

x3.Sub(x3, threeX)
x3.Add(x3, curve.B)
x3.Mod(x3, curve.P)
return x3
}

func defaultSqrt(x, p *big.Int) *big.Int {
var r big.Int
if nil == r.ModSqrt(x, p) {
return nil // x is not a square
}
return &r
}
51 changes: 51 additions & 0 deletions core/crypto/draft-irtf-cfrg-vrf-06/conversion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2020 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package vrf

import (
"bytes"
"fmt"
"math/big"
"testing"
)

func TestI2OSP(t *testing.T) {
for i, tc := range []struct {
x int64
xLen uint
want []byte
wantPanic bool
}{
{x: 1, xLen: 1, want: []byte{0x01}},
{x: 2, xLen: 1, want: []byte{0x02}},
{x: 2, xLen: 2, want: []byte{0, 2}},
{x: 256, xLen: 8, want: []byte{0, 0, 0, 0, 0, 0, 1, 0}},
{x: 256, xLen: 1, wantPanic: true},
{x: 255, xLen: 1, want: []byte{0xff}},
} {
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
defer func() {
r := recover()
if panicked := r != nil; panicked != tc.wantPanic {
t.Errorf("Panicked: %v, wantPanic %v", r, tc.wantPanic)
}
}()

if got := I2OSP(big.NewInt(tc.x), tc.xLen); !bytes.Equal(got, tc.want) {
t.Errorf("I2OSP(%v, %v): %v, want %v", tc.x, tc.xLen, got, tc.want)
}
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sizeofC�(
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<hU��)Q~��i��"�o�f�^���A&IY��K�q���W"ӣ>�ſ�+� ^јdExample of ECDSA
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<hU��)Q~��i��"�o�f�^���A&IY��K�q���W"ӣ��H$ X���ç�a���nqu�yme�sa
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!����,���f�k�{V����g�@�rV��K�T���ҳ���O�,��[R M�ī
|Tg J�K����T��⺠�te
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V����g�@�rV��K�T���ҳ���O�,��[R M�ī
|Tg J�K����T��⺠�te
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!ܤ�9�}���/�����~��V���W�$4�l͇�>�����������H$ X�H��ç�a���nqu�yme�sa
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V����g�@�rV��K�T���ҳ���O�,��[R M�īc
|T J�K���T��⺠��te
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<h{/Fp&IY��K�q���W"ӣ>�ſ�+� ^јdExample of ECDSA with ansip256r1 an
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<hUGoStr<-chaning��"�o�f�^���A&IY��K�q���W"ӣ>�ſ�+� ^јdExample of
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
���E�uk\!Wg�֓NP��6�{�b+g!�ܤ�9�}���/�����~��V���W�$4�l͇�>�����������H$ X�H��ç�a���nqu�yme�sa
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<hU��)Q~��i��"�o�f�^��AZh6��?lyn6{/Fp&IY��K�q���W"ӣ>�ſ�+� ^јdEx
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V����g�@�rV��K�T�������O�,��[R M�īc
|Tg J�K����T��⺠�te
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V��V��K�T���ҳ���g�@�rV��K�T���ҳ���O�,��[R M�īc
|Tg J�K��
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V��V��K�T���ҳ���g�@�rV��K�T���ҳ���O�,��[R M�īU
|Tg J�K��
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�ܤ�9�}���/�����~��V���W�$4�l͇�M�����������H$ X���ç�a���nqu�yme�sa
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�ܤ�9�}���/�����~��V���W�$4�l͇�>�����������H$ X���ç�a���nqu�yme�sa
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions core/crypto/draft-irtf-cfrg-vrf-06/corpus/testvector-1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�ܤ�9�}���/�����~��V���W�$4�l͇�>�����������H$ X�H��ç�a���nqu�yme�sample
Expand Down
2 changes: 2 additions & 0 deletions core/crypto/draft-irtf-cfrg-vrf-06/corpus/testvector-2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ɯ��E�uk\!Wg�֓NP��6�{�b+g!�:�,���f�k�{V����g�@�rV��K�T���ҳ���O�,��[R M�īc
|Tg J�K����T��⺠�test
1 change: 1 addition & 0 deletions core/crypto/draft-irtf-cfrg-vrf-06/corpus/testvector-3
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
,�AA�{$̌;��? *l諹}�I�P�����;:��<hU��)Q~��i��"�o�f�^���AZh6��?lyn6{/Fp&IY��K�q���W"ӣ>�ſ�+� ^јdExample of ECDSA with ansip256r1 and SHA-256
Expand Down
Loading