sonr/crypto/core/curves/ec_point.go

252 lines
6.3 KiB
Go
Raw Normal View History

feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies**
2024-11-23 01:28:58 -05:00
//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package curves
import (
"crypto/elliptic"
"encoding/json"
"fmt"
"math/big"
"github.com/onsonr/sonr/crypto/core"
feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies**
2024-11-23 01:28:58 -05:00
"github.com/dustinxie/ecc"
"github.com/onsonr/sonr/crypto/internal"
feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies**
2024-11-23 01:28:58 -05:00
)
var curveNameToID = map[string]byte{
"secp256k1": 0,
"P-224": 1,
"P-256": 2,
"P-384": 3,
"P-521": 4,
}
var curveIDToName = map[byte]func() elliptic.Curve{
0: ecc.P256k1,
1: elliptic.P224,
2: elliptic.P256,
3: elliptic.P384,
4: elliptic.P521,
}
var curveMapper = map[string]func() elliptic.Curve{
"secp256k1": ecc.P256k1,
"P-224": elliptic.P224,
"P-256": elliptic.P256,
"P-384": elliptic.P384,
"P-521": elliptic.P521,
}
// EcPoint represents an elliptic curve Point
type EcPoint struct {
Curve elliptic.Curve
X, Y *big.Int
}
// EcPointJSON encapsulates the data that is serialized to JSON
// used internally and not for external use. Public so other pieces
// can use for serialization
type EcPointJSON struct {
X *big.Int `json:"x"`
Y *big.Int `json:"y"`
CurveName string `json:"curve_name"`
}
// MarshalJSON serializes EcPoint to JSON
func (a EcPoint) MarshalJSON() ([]byte, error) {
return json.Marshal(EcPointJSON{
CurveName: a.Curve.Params().Name,
X: a.X,
Y: a.Y,
})
}
// UnmarshalJSON deserializes JSON to EcPoint
func (a *EcPoint) UnmarshalJSON(bytes []byte) error {
data := new(EcPointJSON)
err := json.Unmarshal(bytes, data)
if err != nil {
return err
}
if mapper, ok := curveMapper[data.CurveName]; ok {
a.Curve = mapper()
a.X = data.X
a.Y = data.Y
return nil
}
return fmt.Errorf("unknown curve deserialized")
}
// MarshalBinary serializes EcPoint to binary
func (a *EcPoint) MarshalBinary() ([]byte, error) {
result := [65]byte{}
if code, ok := curveNameToID[a.Curve.Params().Name]; ok {
result[0] = code
a.X.FillBytes(result[1:33])
a.Y.FillBytes(result[33:65])
return result[:], nil
}
return nil, fmt.Errorf("unknown curve serialized")
}
// UnmarshalBinary deserializes binary to EcPoint
func (a *EcPoint) UnmarshalBinary(data []byte) error {
if mapper, ok := curveIDToName[data[0]]; ok {
a.Curve = mapper()
a.X = new(big.Int).SetBytes(data[1:33])
a.Y = new(big.Int).SetBytes(data[33:65])
return nil
}
return fmt.Errorf("unknown curve deserialized")
}
// IsValid checks if the point is valid
func (a EcPoint) IsValid() bool {
return a.IsOnCurve() || a.IsIdentity()
}
// IsOnCurve checks if the point is on the curve
func (a EcPoint) IsOnCurve() bool {
return a.Curve.IsOnCurve(a.X, a.Y)
}
// IsIdentity returns true if this Point is the Point at infinity
func (a EcPoint) IsIdentity() bool {
x := core.ConstantTimeEqByte(a.X, core.Zero)
y := core.ConstantTimeEqByte(a.Y, core.Zero)
return (x & y) == 1
}
// Equals return true if a and b have the same x,y coordinates
func (a EcPoint) Equals(b *EcPoint) bool {
if !sameCurve(&a, b) {
return false
}
x := core.ConstantTimeEqByte(a.X, b.X)
y := core.ConstantTimeEqByte(a.Y, b.Y)
return (x & y) == 1
}
// IsBasePoint returns true if this Point is curve's base Point
func (a EcPoint) IsBasePoint() bool {
p := a.Curve.Params()
x := core.ConstantTimeEqByte(a.X, p.Gx)
y := core.ConstantTimeEqByte(a.Y, p.Gy)
return (x & y) == 1
}
// reduceModN normalizes the Scalar to a positive element smaller than the base Point order.
func reduceModN(curve elliptic.Curve, k *big.Int) *big.Int {
return new(big.Int).Mod(k, curve.Params().N)
}
// Add performs elliptic curve addition on two points
func (a *EcPoint) Add(b *EcPoint) (*EcPoint, error) {
if a == nil || b == nil {
return nil, internal.ErrNilArguments
}
if !sameCurve(a, b) {
return nil, internal.ErrPointsDistinctCurves
}
p := &EcPoint{Curve: a.Curve}
p.X, p.Y = a.Curve.Add(a.X, a.Y, b.X, b.Y)
if !p.IsValid() {
return nil, internal.ErrNotOnCurve
}
return p, nil
}
// Neg returns the negation of a Weierstrass Point.
func (a *EcPoint) Neg() (*EcPoint, error) {
if a == nil {
return nil, internal.ErrNilArguments
}
p := &EcPoint{Curve: a.Curve, X: a.X, Y: new(big.Int).Sub(a.Curve.Params().P, a.Y)}
if !p.IsValid() {
return nil, internal.ErrNotOnCurve
}
return p, nil
}
// ScalarMult multiplies this Point by a Scalar
func (a *EcPoint) ScalarMult(k *big.Int) (*EcPoint, error) {
if a == nil || k == nil {
return nil, fmt.Errorf("cannot multiply nil Point or element")
}
n := reduceModN(a.Curve, k)
p := new(EcPoint)
p.Curve = a.Curve
p.X, p.Y = a.Curve.ScalarMult(a.X, a.Y, n.Bytes())
if !p.IsValid() {
return nil, fmt.Errorf("result not on the curve")
}
return p, nil
}
// NewScalarBaseMult creates a Point from the base Point multiplied by a field element
func NewScalarBaseMult(curve elliptic.Curve, k *big.Int) (*EcPoint, error) {
if curve == nil || k == nil {
return nil, fmt.Errorf("nil parameters are not supported")
}
n := reduceModN(curve, k)
p := new(EcPoint)
p.Curve = curve
p.X, p.Y = curve.ScalarBaseMult(n.Bytes())
if !p.IsValid() {
return nil, fmt.Errorf("result not on the curve")
}
return p, nil
}
// Bytes returns the bytes represented by this Point with x || y
func (a EcPoint) Bytes() []byte {
fieldSize := internal.CalcFieldSize(a.Curve)
out := make([]byte, fieldSize*2)
a.X.FillBytes(out[0:fieldSize])
a.Y.FillBytes(out[fieldSize : fieldSize*2])
return out
}
// PointFromBytesUncompressed outputs uncompressed X || Y similar to
// https://www.secg.org/sec1-v1.99.dif.pdf section 2.2 and 2.3
func PointFromBytesUncompressed(curve elliptic.Curve, b []byte) (*EcPoint, error) {
fieldSize := internal.CalcFieldSize(curve)
if len(b) != fieldSize*2 {
return nil, fmt.Errorf("invalid number of bytes")
}
p := &EcPoint{
Curve: curve,
X: new(big.Int).SetBytes(b[:fieldSize]),
Y: new(big.Int).SetBytes(b[fieldSize:]),
}
if !p.IsValid() {
return nil, fmt.Errorf("invalid Point")
}
return p, nil
}
// sameCurve determines if points a,b appear to be from the same curve
func sameCurve(a, b *EcPoint) bool {
if a == b {
return true
}
if a == nil || b == nil {
return false
}
aParams := a.Curve.Params()
bParams := b.Curve.Params()
return aParams.P.Cmp(bParams.P) == 0 &&
aParams.N.Cmp(bParams.N) == 0 &&
aParams.B.Cmp(bParams.B) == 0 &&
aParams.BitSize == bParams.BitSize &&
aParams.Gx.Cmp(bParams.Gx) == 0 &&
aParams.Gy.Cmp(bParams.Gy) == 0 &&
aParams.Name == bParams.Name
}