Rebrand to Tutus - update license, workflows, and dependencies

This commit is contained in:
Tutus Development 2025-12-27 15:45:25 +00:00
parent 6724b49798
commit 24720bf5a6
10 changed files with 469 additions and 469 deletions

View File

@ -1,9 +1,9 @@
name: DCO check
on:
pull_request:
branches: [ "master" ]
jobs:
dco:
uses: nspcc-dev/.github/.github/workflows/dco.yml@master
name: DCO check
on:
pull_request:
branches: [ "master" ]
jobs:
dco:
uses: nspcc-dev/.github/.github/workflows/dco.yml@master

View File

@ -1,116 +1,116 @@
name: Tests
on:
pull_request:
branches:
- master
types: [ opened, synchronize ]
workflow_dispatch:
jobs:
lint:
name: Lint
uses: nspcc-dev/.github/.github/workflows/go-linter.yml@master
test_cover:
name: Coverage
runs-on: ubuntu-latest
env:
CGO_ENABLED: 0
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
- name: Write coverage profile
run: go test ./... -coverprofile=./coverage.txt -covermode=atomic
- name: Upload coverage results to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
slug: nspcc-dev/rfc6979
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.txt
verbose: true
tests:
name: Run tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
go_versions: [ '1.24', '1.25' ]
exclude:
- os: macos-latest
go_versions: '1.24'
- os: windows-latest
go_versions: '1.24'
- os: ubuntu-latest
go_versions: '1.25'
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '${{ matrix.go_versions }}'
cache: true
- name: Run tests
run: go test -race ./...
codeql:
name: CodeQL
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
name: Tests
on:
pull_request:
branches:
- master
types: [ opened, synchronize ]
workflow_dispatch:
jobs:
lint:
name: Lint
uses: nspcc-dev/.github/.github/workflows/go-linter.yml@master
test_cover:
name: Coverage
runs-on: ubuntu-latest
env:
CGO_ENABLED: 0
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
- name: Write coverage profile
run: go test ./... -coverprofile=./coverage.txt -covermode=atomic
- name: Upload coverage results to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
slug: nspcc-dev/rfc6979
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.txt
verbose: true
tests:
name: Run tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
go_versions: [ '1.24', '1.25' ]
exclude:
- os: macos-latest
go_versions: '1.24'
- os: windows-latest
go_versions: '1.24'
- os: ubuntu-latest
go_versions: '1.25'
fail-fast: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '${{ matrix.go_versions }}'
cache: true
- name: Run tests
run: go test -race ./...
codeql:
name: CodeQL
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

46
.gitignore vendored
View File

@ -1,23 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
.golangci.yml
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
.golangci.yml

View File

@ -1,4 +1,4 @@
language: go
go:
- 1.12.x
- 1.13.x
language: go
go:
- 1.12.x
- 1.13.x

42
LICENSE
View File

@ -1,21 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Coda Hale
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The MIT License (MIT)
Copyright (c) 2014 Coda Hale
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

84
dsa.go
View File

@ -1,42 +1,42 @@
package rfc6979
import (
"crypto/dsa" //nolint:staticcheck
"hash"
"math/big"
)
// SignDSA signs an arbitrary length hash (which should be the result of hashing
// a larger message) using the private key, priv. It returns the signature as a
// pair of integers.
//
// Deprecated: crypto/dsa package is deprecated in Go, so please swtich to ECDSA.
// This method can be removed in future versions.
func SignDSA(priv *dsa.PrivateKey, hash []byte, alg func() hash.Hash) (r, s *big.Int, err error) {
n := priv.Q.BitLen()
if n&7 != 0 {
err = dsa.ErrInvalidPublicKey
return
}
generateSecret(priv.Q, priv.X, alg, hash, func(k *big.Int, z *big.Int, _ []byte) bool {
r = new(big.Int).Exp(priv.G, k, priv.P)
r.Mod(r, priv.Q)
if r.Sign() == 0 {
return false
}
inv := k.ModInverse(k, priv.Q)
s = new(big.Int).Mul(priv.X, r)
s.Add(s, z)
s.Mod(s, priv.Q)
s.Mul(s, inv)
s.Mod(s, priv.Q)
return s.Sign() != 0
})
return
}
package rfc6979
import (
"crypto/dsa" //nolint:staticcheck
"hash"
"math/big"
)
// SignDSA signs an arbitrary length hash (which should be the result of hashing
// a larger message) using the private key, priv. It returns the signature as a
// pair of integers.
//
// Deprecated: crypto/dsa package is deprecated in Go, so please swtich to ECDSA.
// This method can be removed in future versions.
func SignDSA(priv *dsa.PrivateKey, hash []byte, alg func() hash.Hash) (r, s *big.Int, err error) {
n := priv.Q.BitLen()
if n&7 != 0 {
err = dsa.ErrInvalidPublicKey
return
}
generateSecret(priv.Q, priv.X, alg, hash, func(k *big.Int, z *big.Int, _ []byte) bool {
r = new(big.Int).Exp(priv.G, k, priv.P)
r.Mod(r, priv.Q)
if r.Sign() == 0 {
return false
}
inv := k.ModInverse(k, priv.Q)
s = new(big.Int).Mul(priv.X, r)
s.Add(s, z)
s.Mod(s, priv.Q)
s.Mul(s, inv)
s.Mod(s, priv.Q)
return s.Sign() != 0
})
return
}

View File

@ -1,38 +1,38 @@
package rfc6979
import (
"crypto/ecdsa"
"hash"
"math/big"
)
// SignECDSA signs an arbitrary length hash (which should be the result of
// hashing a larger message) using the private key, priv. It returns the
// signature as a pair of integers.
//
// Will panic if invalid private key (>N for the curve) is passed.
func SignECDSA(priv *ecdsa.PrivateKey, hash []byte, alg func() hash.Hash) (r, s *big.Int) {
c := priv.Curve
N := c.Params().N
generateSecret(N, priv.D, alg, hash, func(k *big.Int, e *big.Int, t []byte) bool {
k.FillBytes(t)
r, _ = priv.ScalarBaseMult(t)
r.Mod(r, N)
if r.Sign() == 0 {
return false
}
inv := k.ModInverse(k, N)
s = new(big.Int).Mul(priv.D, r)
s.Add(s, e)
s.Mul(s, inv)
s.Mod(s, N)
return s.Sign() != 0
})
return
}
package rfc6979
import (
"crypto/ecdsa"
"hash"
"math/big"
)
// SignECDSA signs an arbitrary length hash (which should be the result of
// hashing a larger message) using the private key, priv. It returns the
// signature as a pair of integers.
//
// Will panic if invalid private key (>N for the curve) is passed.
func SignECDSA(priv *ecdsa.PrivateKey, hash []byte, alg func() hash.Hash) (r, s *big.Int) {
c := priv.Curve
N := c.Params().N
generateSecret(N, priv.D, alg, hash, func(k *big.Int, e *big.Int, t []byte) bool {
k.FillBytes(t)
r, _ = priv.ScalarBaseMult(t)
r.Mod(r, N)
if r.Sign() == 0 {
return false
}
inv := k.ModInverse(k, N)
s = new(big.Int).Mul(priv.D, r)
s.Add(s, e)
s.Mul(s, inv)
s.Mod(s, N)
return s.Sign() != 0
})
return
}

View File

@ -1,74 +1,74 @@
package rfc6979
import (
"crypto/dsa" //nolint:staticcheck
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha1"
"crypto/sha512"
"fmt"
)
// Generates a 521-bit ECDSA key, uses SHA-512 to sign a message, then verifies
// it.
func ExampleSignECDSA() {
// Generate a key pair.
// You need a high-quality PRNG for this.
k, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
fmt.Println(err)
return
}
// Hash a message.
alg := sha512.New()
alg.Write([]byte("I am a potato."))
hash := alg.Sum(nil)
// Sign the message. You don't need a PRNG for this.
r, s := SignECDSA(k, hash, sha512.New)
if !ecdsa.Verify(&k.PublicKey, hash, r, s) {
fmt.Println("Invalid signature!")
}
// Output:
}
// Generates a 1024-bit DSA key, uses SHA-1 to sign a message, then verifies it.
func ExampleSignDSA() {
// Here I'm generating some DSA params, but you should really pre-generate
// these and re-use them, since this takes a long time and isn't necessary.
k := new(dsa.PrivateKey)
if err := dsa.GenerateParameters(&k.Parameters, rand.Reader, dsa.L1024N160); err != nil {
fmt.Println(err)
return
}
// Generate a key pair.
// You need a high-quality PRNG for this.
err := dsa.GenerateKey(k, rand.Reader)
if err != nil {
fmt.Println(err)
return
}
// Hash a message.
alg := sha1.New()
alg.Write([]byte("I am a potato."))
hash := alg.Sum(nil)
// Sign the message. You don't need a PRNG for this.
r, s, err := SignDSA(k, hash, sha1.New)
if err != nil {
fmt.Println(err)
return
}
if !dsa.Verify(&k.PublicKey, hash, r, s) {
fmt.Println("Invalid signature!")
}
// Output:
}
package rfc6979
import (
"crypto/dsa" //nolint:staticcheck
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha1"
"crypto/sha512"
"fmt"
)
// Generates a 521-bit ECDSA key, uses SHA-512 to sign a message, then verifies
// it.
func ExampleSignECDSA() {
// Generate a key pair.
// You need a high-quality PRNG for this.
k, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
fmt.Println(err)
return
}
// Hash a message.
alg := sha512.New()
alg.Write([]byte("I am a potato."))
hash := alg.Sum(nil)
// Sign the message. You don't need a PRNG for this.
r, s := SignECDSA(k, hash, sha512.New)
if !ecdsa.Verify(&k.PublicKey, hash, r, s) {
fmt.Println("Invalid signature!")
}
// Output:
}
// Generates a 1024-bit DSA key, uses SHA-1 to sign a message, then verifies it.
func ExampleSignDSA() {
// Here I'm generating some DSA params, but you should really pre-generate
// these and re-use them, since this takes a long time and isn't necessary.
k := new(dsa.PrivateKey)
if err := dsa.GenerateParameters(&k.Parameters, rand.Reader, dsa.L1024N160); err != nil {
fmt.Println(err)
return
}
// Generate a key pair.
// You need a high-quality PRNG for this.
err := dsa.GenerateKey(k, rand.Reader)
if err != nil {
fmt.Println(err)
return
}
// Hash a message.
alg := sha1.New()
alg.Write([]byte("I am a potato."))
hash := alg.Sum(nil)
// Sign the message. You don't need a PRNG for this.
r, s, err := SignDSA(k, hash, sha1.New)
if err != nil {
fmt.Println(err)
return
}
if !dsa.Verify(&k.PublicKey, hash, r, s) {
fmt.Println("Invalid signature!")
}
// Output:
}

View File

@ -1,114 +1,114 @@
/*
Package rfc6979 is an implementation of RFC 6979's deterministic DSA.
Such signatures are compatible with standard Digital Signature Algorithm
(DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) digital
signatures and can be processed with unmodified verifiers, which need not be
aware of the procedure described therein. Deterministic signatures retain
the cryptographic security features associated with digital signatures but
can be more easily implemented in various environments, since they do not
need access to a source of high-quality randomness.
(https://tools.ietf.org/html/rfc6979)
Provides functions similar to crypto/dsa and crypto/ecdsa.
*/
package rfc6979
import (
"crypto/hmac"
"hash"
"math/big"
)
// mac returns an HMAC result for the given key and message as well as
// hmac hash instance itself (that can be reused for the same key after reset).
func mac(alg func() hash.Hash, k, m, buf []byte) ([]byte, hash.Hash) {
h := hmac.New(alg, k)
h.Write(m)
return h.Sum(buf[:0]), h
}
// macReuse allows to reuse already initialized hmac for the next
// message using the same key.
func macReuse(h hash.Hash, m, buf []byte) []byte {
h.Reset()
h.Write(m)
return h.Sum(buf[:0])
}
// https://tools.ietf.org/html/rfc6979#section-2.3.2
func bits2int(in []byte, qlen int) *big.Int {
vlen := len(in) * 8
v := new(big.Int).SetBytes(in)
if vlen > qlen {
v.Rsh(v, uint(vlen-qlen))
}
return v
}
// bits2IntModQ implements an integer part of bits2octets defined
// in https://tools.ietf.org/html/rfc6979#section-2.3.4
func bits2IntModQ(in []byte, q *big.Int, qlen int) *big.Int {
z1 := bits2int(in, qlen)
if z1.Cmp(q) < 0 {
return z1
}
return z1.Sub(z1, q)
}
var one = big.NewInt(1)
// https://tools.ietf.org/html/rfc6979#section-3.2
func generateSecret(q, x *big.Int, alg func() hash.Hash, hash []byte, test func(*big.Int, *big.Int, []byte) bool) {
qlen := q.BitLen()
holen := alg().Size()
rolen := (qlen + 7) >> 3
var bx = make([]byte, 2*rolen)
x.FillBytes(bx[:rolen]) // int2octets per https://tools.ietf.org/html/rfc6979#section-2.3.3
var hashInt = bits2IntModQ(hash, q, qlen)
hashInt.FillBytes(bx[rolen:]) // int2octets per https://tools.ietf.org/html/rfc6979#section-2.3.3
// Step B
var v = make([]byte, holen, holen+1+len(bx)) // see appends below
for i := range holen {
v[i] = 0x01
}
// Step C
k := make([]byte, holen)
// Step D
k, _ = mac(alg, k, append(append(v, 0x00), bx...), k)
// Step E
v, h := mac(alg, k, v, v)
// Step F
k = macReuse(h, append(append(v, 0x01), bx...), k)
// Step G
v, h = mac(alg, k, v, v)
// Step H
var t = make([]byte, qlen/8)
for {
// Step H1
t = t[:0]
// Step H2
for len(t) < qlen/8 {
v = macReuse(h, v, v)
t = append(t, v...)
}
// Step H3
secret := bits2int(t, qlen)
if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 && test(secret, hashInt, t) {
return
}
k, _ = mac(alg, k, append(v, 0x00), k)
v, h = mac(alg, k, v, v)
}
}
/*
Package rfc6979 is an implementation of RFC 6979's deterministic DSA.
Such signatures are compatible with standard Digital Signature Algorithm
(DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) digital
signatures and can be processed with unmodified verifiers, which need not be
aware of the procedure described therein. Deterministic signatures retain
the cryptographic security features associated with digital signatures but
can be more easily implemented in various environments, since they do not
need access to a source of high-quality randomness.
(https://tools.ietf.org/html/rfc6979)
Provides functions similar to crypto/dsa and crypto/ecdsa.
*/
package rfc6979
import (
"crypto/hmac"
"hash"
"math/big"
)
// mac returns an HMAC result for the given key and message as well as
// hmac hash instance itself (that can be reused for the same key after reset).
func mac(alg func() hash.Hash, k, m, buf []byte) ([]byte, hash.Hash) {
h := hmac.New(alg, k)
h.Write(m)
return h.Sum(buf[:0]), h
}
// macReuse allows to reuse already initialized hmac for the next
// message using the same key.
func macReuse(h hash.Hash, m, buf []byte) []byte {
h.Reset()
h.Write(m)
return h.Sum(buf[:0])
}
// https://tools.ietf.org/html/rfc6979#section-2.3.2
func bits2int(in []byte, qlen int) *big.Int {
vlen := len(in) * 8
v := new(big.Int).SetBytes(in)
if vlen > qlen {
v.Rsh(v, uint(vlen-qlen))
}
return v
}
// bits2IntModQ implements an integer part of bits2octets defined
// in https://tools.ietf.org/html/rfc6979#section-2.3.4
func bits2IntModQ(in []byte, q *big.Int, qlen int) *big.Int {
z1 := bits2int(in, qlen)
if z1.Cmp(q) < 0 {
return z1
}
return z1.Sub(z1, q)
}
var one = big.NewInt(1)
// https://tools.ietf.org/html/rfc6979#section-3.2
func generateSecret(q, x *big.Int, alg func() hash.Hash, hash []byte, test func(*big.Int, *big.Int, []byte) bool) {
qlen := q.BitLen()
holen := alg().Size()
rolen := (qlen + 7) >> 3
var bx = make([]byte, 2*rolen)
x.FillBytes(bx[:rolen]) // int2octets per https://tools.ietf.org/html/rfc6979#section-2.3.3
var hashInt = bits2IntModQ(hash, q, qlen)
hashInt.FillBytes(bx[rolen:]) // int2octets per https://tools.ietf.org/html/rfc6979#section-2.3.3
// Step B
var v = make([]byte, holen, holen+1+len(bx)) // see appends below
for i := range holen {
v[i] = 0x01
}
// Step C
k := make([]byte, holen)
// Step D
k, _ = mac(alg, k, append(append(v, 0x00), bx...), k)
// Step E
v, h := mac(alg, k, v, v)
// Step F
k = macReuse(h, append(append(v, 0x01), bx...), k)
// Step G
v, h = mac(alg, k, v, v)
// Step H
var t = make([]byte, qlen/8)
for {
// Step H1
t = t[:0]
// Step H2
for len(t) < qlen/8 {
v = macReuse(h, v, v)
t = append(t, v...)
}
// Step H3
secret := bits2int(t, qlen)
if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 && test(secret, hashInt, t) {
return
}
k, _ = mac(alg, k, append(v, 0x00), k)
v, h = mac(alg, k, v, v)
}
}

View File

@ -1,28 +1,28 @@
package rfc6979
import (
"crypto/sha256"
"encoding/hex"
"math/big"
"testing"
)
// https://tools.ietf.org/html/rfc6979#appendix-A.1
func TestGenerateSecret(t *testing.T) {
q, _ := new(big.Int).SetString("4000000000000000000020108A2E0CC0D99F8A5EF", 16)
x, _ := new(big.Int).SetString("09A4D6792295A7F730FC3F2B49CBC0F62E862272F", 16)
hash, _ := hex.DecodeString("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF")
expected, _ := new(big.Int).SetString("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16)
var actual *big.Int
generateSecret(q, x, sha256.New, hash, func(k *big.Int, _ *big.Int, _ []byte) bool {
actual = k
return true
})
if actual.Cmp(expected) != 0 {
t.Errorf("Expected %x, got %x", expected, actual)
}
}
package rfc6979
import (
"crypto/sha256"
"encoding/hex"
"math/big"
"testing"
)
// https://tools.ietf.org/html/rfc6979#appendix-A.1
func TestGenerateSecret(t *testing.T) {
q, _ := new(big.Int).SetString("4000000000000000000020108A2E0CC0D99F8A5EF", 16)
x, _ := new(big.Int).SetString("09A4D6792295A7F730FC3F2B49CBC0F62E862272F", 16)
hash, _ := hex.DecodeString("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF")
expected, _ := new(big.Int).SetString("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16)
var actual *big.Int
generateSecret(q, x, sha256.New, hash, func(k *big.Int, _ *big.Int, _ []byte) bool {
actual = k
return true
})
if actual.Cmp(expected) != 0 {
t.Errorf("Expected %x, got %x", expected, actual)
}
}