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

Commit

Permalink
Add Scalar.SetUInt64, remove Scalar.SetBigInt, add Hex() and DecodeHe… (
Browse files Browse the repository at this point in the history
#57)

* Add Scalar.SetUInt64, remove Scalar.SetBigInt, add Hex() and DecodeHex(), add tests

---------

Signed-off-by: bytemare <[email protected]>
  • Loading branch information
bytemare authored Jun 10, 2024
1 parent 4ef5e74 commit cd6020a
Show file tree
Hide file tree
Showing 24 changed files with 456 additions and 165 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.projectKey=bytemare_crypto
-Dsonar.organization=bytemare-github
-Dsonar.projectKey=crypto
-Dsonar.organization=bytemare
-Dsonar.go.coverage.reportPaths=.github/coverage.out
-Dsonar.sources=.
-Dsonar.test.exclusions=tests/**
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,12 @@ type Scalar interface {
LessOrEqual(Scalar) int
IsZero() bool
Set(Scalar) Scalar
SetInt(big.Int) error
SetUInt64(uint64) Scalar
Copy() Scalar
Encode() []byte
Decode(in []byte) error
Hex() string
HexDecode([]byte) error
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
}
Expand All @@ -95,6 +97,8 @@ type Element interface {
Encode() []byte
XCoordinate() []byte
Decode(data []byte) error
Hex() string
HexDecode([]byte) error
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
}
Expand Down
14 changes: 14 additions & 0 deletions element.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,20 @@ func (e *Element) Decode(data []byte) error {
return nil
}

// Hex returns the fixed-sized hexadecimal encoding of e.
func (e *Element) Hex() string {
return e.Element.Hex()
}

// DecodeHex sets e to the decoding of the hex encoded element.
func (e *Element) DecodeHex(h string) error {
if err := e.Element.DecodeHex(h); err != nil {
return fmt.Errorf("element DecodeHex: %w", err)
}

return nil
}

// MarshalBinary returns the compressed byte encoding of the element.
func (e *Element) MarshalBinary() ([]byte, error) {
dec, err := e.Element.MarshalBinary()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
filippo.io/edwards25519 v1.1.0
filippo.io/nistec v0.0.3
github.com/bytemare/hash2curve v0.3.0
github.com/bytemare/secp256k1 v0.1.2
github.com/bytemare/secp256k1 v0.1.4
github.com/gtank/ristretto255 v0.1.2
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/bytemare/hash v0.3.0 h1:RqFMt3mqpF7UxLdjBrsOZm/2cz0cQiAOnYc9gDLopWE=
github.com/bytemare/hash v0.3.0/go.mod h1:YKOBchL0l8hRLFinVCL8YUKokGNIMhrWEHPHo3EV7/M=
github.com/bytemare/hash2curve v0.3.0 h1:41Npcbc+u/E252A5aCMtxDcz7JPkkX1QzShneTFm4eg=
github.com/bytemare/hash2curve v0.3.0/go.mod h1:itj45U8uqvCtWC0eCswIHVHswXcEHkpFui7gfJdPSfQ=
github.com/bytemare/secp256k1 v0.1.2 h1:aM+p/+0y1h0SZWqS/yzjGPzffVFubJvwLjUgodFEWOo=
github.com/bytemare/secp256k1 v0.1.2/go.mod h1:Pxb9miDs8PTt5mOktvvXiRflvLxI1wdxbXrc6IYsaho=
github.com/bytemare/secp256k1 v0.1.4 h1:6F1yP6RiUiWwH7AsGHsHktmHm24QcetdDcc39roBd2M=
github.com/bytemare/secp256k1 v0.1.4/go.mod h1:Pxb9miDs8PTt5mOktvvXiRflvLxI1wdxbXrc6IYsaho=
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
Expand Down
16 changes: 16 additions & 0 deletions internal/edwards25519/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package edwards25519

import (
"encoding/hex"
"fmt"

ed "filippo.io/edwards25519"
Expand Down Expand Up @@ -163,6 +164,21 @@ func (e *Element) Decode(data []byte) error {
return nil
}

// Hex returns the fixed-sized hexadecimal encoding of e.
func (e *Element) Hex() string {
return hex.EncodeToString(e.Encode())
}

// DecodeHex sets e to the decoding of the hex encoded element.
func (e *Element) DecodeHex(h string) error {
b, err := hex.DecodeString(h)
if err != nil {
return fmt.Errorf("%w", err)
}

return e.Decode(b)
}

// MarshalBinary returns the compressed byte encoding of the element.
func (e *Element) MarshalBinary() (data []byte, err error) {
return e.Encode(), nil
Expand Down
37 changes: 28 additions & 9 deletions internal/edwards25519/scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
package edwards25519

import (
"encoding/binary"
"encoding/hex"
"fmt"
"math/big"

Expand Down Expand Up @@ -268,18 +270,20 @@ func (s *Scalar) Set(scalar internal.Scalar) internal.Scalar {
return s
}

// SetInt sets s to i modulo the field order, and returns an error if one occurs.
func (s *Scalar) SetInt(i *big.Int) error {
a := new(big.Int).Set(i)
// SetUInt64 sets s to i modulo the field order, and returns an error if one occurs.
func (s *Scalar) SetUInt64(i uint64) internal.Scalar {
encoded := make([]byte, canonicalEncodingLength)
binary.LittleEndian.PutUint64(encoded, i)

bytes := make([]byte, 32)
bytes = a.Mod(a, &order).FillBytes(bytes)

for j, k := 0, len(bytes)-1; j < k; j, k = j+1, k-1 {
bytes[j], bytes[k] = bytes[k], bytes[j]
sc, err := decodeScalar(encoded)
if err != nil {
// This cannot happen, since any uint64 is smaller than the order.
panic(fmt.Sprintf("unexpected decoding of uint64 scalar: %s", err))
}

return s.Decode(bytes)
s.set(sc)

return s
}

func (s *Scalar) copy() *Scalar {
Expand Down Expand Up @@ -325,6 +329,21 @@ func (s *Scalar) Decode(in []byte) error {
return nil
}

// Hex returns the fixed-sized hexadecimal encoding of s.
func (s *Scalar) Hex() string {
return hex.EncodeToString(s.Encode())
}

// DecodeHex sets s to the decoding of the hex encoded scalar.
func (s *Scalar) DecodeHex(h string) error {
b, err := hex.DecodeString(h)
if err != nil {
return fmt.Errorf("%w", err)
}

return s.Decode(b)
}

// MarshalBinary returns the compressed byte encoding of the scalar.
func (s *Scalar) MarshalBinary() (data []byte, err error) {
return s.Encode(), nil
Expand Down
10 changes: 9 additions & 1 deletion internal/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
// Package internal defines simple and abstract APIs to group Elements and Scalars.
package internal

import "encoding"
import (
"encoding"
)

// Element interface abstracts common operations on an Element in a prime-order Group.
type Element interface {
Expand Down Expand Up @@ -55,6 +57,12 @@ type Element interface {
// Decode sets the receiver to a decoding of the input data, and returns an error on failure.
Decode(data []byte) error

// Hex returns the fixed-sized hexadecimal encoding of e.
Hex() string

// DecodeHex sets e to the decoding of the hex encoded element.
DecodeHex(h string) error

// BinaryMarshaler implementation.
encoding.BinaryMarshaler

Expand Down
25 changes: 25 additions & 0 deletions internal/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package internal

import (
cryptorand "crypto/rand"
"encoding"
"errors"
"fmt"
)
Expand Down Expand Up @@ -52,6 +53,30 @@ var (
ErrParamScalarInvalidEncoding = errors.New("invalid scalar encoding")
)

// An Encoder can encode itself to machine or human-readable forms.
type Encoder interface {
// Encode returns the compressed byte encoding.
Encode() []byte

// Hex returns the fixed-sized hexadecimal encoding.
Hex() string

// BinaryMarshaler implementation.
encoding.BinaryMarshaler
}

// A Decoder can encode itself to machine or human-readable forms.
type Decoder interface {
// Decode sets the receiver to a decoding of the input data, and returns an error on failure.
Decode(data []byte) error

// DecodeHex sets the receiver to the decoding of the hex encoded input.
DecodeHex(h string) error

// BinaryUnmarshaler implementation.
encoding.BinaryUnmarshaler
}

// RandomBytes returns random bytes of length len (wrapper for crypto/rand).
func RandomBytes(length int) []byte {
random := make([]byte, length)
Expand Down
18 changes: 17 additions & 1 deletion internal/nist/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package nist

import (
"crypto/subtle"
"encoding/hex"
"fmt"

"github.com/bytemare/crypto/internal"
Expand Down Expand Up @@ -214,12 +215,27 @@ func (e *Element[P]) XCoordinate() []byte {
// Decode sets the receiver to a decoding of the input data, and returns an error on failure.
func (e *Element[P]) Decode(data []byte) error {
if _, err := e.p.SetBytes(data); err != nil {
return fmt.Errorf("nist element Decode: %w", err)
return fmt.Errorf("%w", err)
}

return nil
}

// Hex returns the fixed-sized hexadecimal encoding of e.
func (e *Element[P]) Hex() string {
return hex.EncodeToString(e.Encode())
}

// DecodeHex sets e to the decoding of the hex encoded element.
func (e *Element[P]) DecodeHex(h string) error {
b, err := hex.DecodeString(h)
if err != nil {
return fmt.Errorf("%w", err)
}

return e.Decode(b)
}

// MarshalBinary returns the compressed byte encoding of the element.
func (e *Element[P]) MarshalBinary() ([]byte, error) {
return e.Encode(), nil
Expand Down
28 changes: 21 additions & 7 deletions internal/nist/scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package nist

import (
"crypto/subtle"
"encoding/hex"
"fmt"
"math/big"

Expand Down Expand Up @@ -112,7 +113,7 @@ func (s *Scalar) Pow(scalar internal.Scalar) internal.Scalar {
return s.One()
}

if scalar.Equal(scalar.Copy().One()) == 1 {
if scalar.Equal(newScalar(s.field).One()) == 1 {
return s
}

Expand Down Expand Up @@ -181,12 +182,10 @@ func (s *Scalar) Set(scalar internal.Scalar) internal.Scalar {
return s
}

// SetInt sets s to i modulo the field order, and returns an error if one occurs.
func (s *Scalar) SetInt(i *big.Int) error {
s.scalar.Set(i)
s.field.Mod(&s.scalar)

return nil
// SetUInt64 sets s to i modulo the field order, and returns an error if one occurs.
func (s *Scalar) SetUInt64(i uint64) internal.Scalar {
s.scalar.SetUint64(i)
return s
}

// Copy returns a copy of the Scalar.
Expand Down Expand Up @@ -233,6 +232,21 @@ func (s *Scalar) Decode(in []byte) error {
return nil
}

// Hex returns the fixed-sized hexadecimal encoding of s.
func (s *Scalar) Hex() string {
return hex.EncodeToString(s.Encode())
}

// DecodeHex sets s to the decoding of the hex encoded scalar.
func (s *Scalar) DecodeHex(h string) error {
b, err := hex.DecodeString(h)
if err != nil {
return fmt.Errorf("%w", err)
}

return s.Decode(b)
}

// MarshalBinary returns the compressed byte encoding of the scalar.
func (s *Scalar) MarshalBinary() ([]byte, error) {
return s.Encode(), nil
Expand Down
16 changes: 16 additions & 0 deletions internal/ristretto/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package ristretto

import (
"encoding/hex"
"fmt"

"github.com/gtank/ristretto255"
Expand Down Expand Up @@ -169,6 +170,21 @@ func (e *Element) Decode(data []byte) error {
return nil
}

// Hex returns the fixed-sized hexadecimal encoding of e.
func (e *Element) Hex() string {
return hex.EncodeToString(e.Encode())
}

// DecodeHex sets e to the decoding of the hex encoded element.
func (e *Element) DecodeHex(h string) error {
b, err := hex.DecodeString(h)
if err != nil {
return fmt.Errorf("%w", err)
}

return e.Decode(b)
}

// MarshalBinary returns the compressed byte encoding of the element.
func (e *Element) MarshalBinary() ([]byte, error) {
return e.Encode(), nil
Expand Down
Loading

0 comments on commit cd6020a

Please sign in to comment.