<commit_before>package ecc

import (
	"errors"
	"fmt"
	"github.com/bfix/gospel/math"
)

// Curve is the elliptic curve used for Bitcoin (Secp256k1)
type Curve struct {
	// P is the generator of the underlying field "F_p"
	// = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
	P *math.Int
	// Gx is the x-coord of the base point
	Gx *math.Int
	// Gy is the y-coord of the base point
	Gy *math.Int
	// N is the order of G
	N *math.Int
	// curve parameter (=7)
	B *math.Int
}

var (
	// Curve is the reference to a curve instance (meant as singleton)
	c = &Curve{
		P:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"),
		Gx: math.NewIntFromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
		Gy: math.NewIntFromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"),
		N:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
		B:  math.SEVEN,
	}
)

// GetCurve returns the singleton curve instance
func GetCurve() *Curve {
	return c
}

// GetBasePoint returns the base Point of the curve
func GetBasePoint() *Point {
	return NewPoint(c.Gx, c.Gy)
}

// MultBase multiplies the base Point of the curve with a scalar value k
func MultBase(k *math.Int) *Point {
	return GetBasePoint().Mult(k)
}

// Inf is the point at "infinity"
var Inf = NewPoint(math.ZERO, math.ZERO)

// Point (x,y) on the curve
type Point struct { // exported Point type
	x, y *math.Int // coordinate values
}

// NewPoint instaniates a new Point
func NewPoint(a, b *math.Int) *Point {
	return &Point{x: a, y: b}
}

// NewPointFromBytes reconstructs a Point from binary representation.
func NewPointFromBytes(b []byte) (p *Point, compr bool, err error) {
	p = NewPoint(math.ZERO, math.ZERO)
	err = nil
	compr = true
	switch b[0] {
	case 0:
	case 4:
		p.x = math.NewIntFromBytes(b[1:33])
		p.y = math.NewIntFromBytes(b[33:])
		compr = false
	case 3:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 1)
		if err != nil {
			return<commit_msg>Added more curve-related methods.<commit_after>package ecc

import (
	"errors"
	"fmt"
	"github.com/bfix/gospel/math"
)

// Curve is the elliptic curve used for Bitcoin (Secp256k1)
type Curve struct {
	// P is the generator of the underlying field "F_p"
	// = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
	P *math.Int
	// Gx is the x-coord of the base point
	Gx *math.Int
	// Gy is the y-coord of the base point
	Gy *math.Int
	// N is the order of G
	N *math.Int
	// curve parameter (=7)
	B *math.Int
}

var (
	// Curve is the reference to a curve instance (meant as singleton)
	c = &Curve{
		P:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"),
		Gx: math.NewIntFromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
		Gy: math.NewIntFromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"),
		N:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
		B:  math.SEVEN,
	}
)

// GetCurve returns the singleton curve instance
func GetCurve() *Curve {
	return c
}

// GetBasePoint returns the base Point of the curve
func GetBasePoint() *Point {
	return NewPoint(c.Gx, c.Gy)
}

// MultBase multiplies the base Point of the curve with a scalar value k
func MultBase(k *math.Int) *Point {
	return GetBasePoint().Mult(k)
}

// Solve the curve equation for given x-ccordinate (returns positive y)
func Solve(x *math.Int) (*math.Int, bool) {
	// compute 'y = +√(x³ + 7)'
	y2 := pAdd(pCub(x), math.SEVEN)
	y, err := math.SqrtModP(y2, c.P)
	return y, err == nil
}

// SignY of a point (y-coordinate) on the Bitcoin curve:
// +1 if above x-axis, -1 if below.
func SignY(p *Point) (int, error) {
	y, ok := Solve(p.X())
	if ok {
		// positive solution?
		if y.Equals(p.Y()) {
			return 1, nil
		}
		// negative solution?
		if y.Equals(c.P.Sub(p.Y())) {
			return -1, nil
		}
	}
	return 0, errors.New("Point not on curve")
}

// Inf is the point at "infinity"
var Inf = NewPoint(math.ZERO, math.ZERO)

// Point (x,y) on the curve
type Point struct { // exported Point type
	x, y *math.Int // coordinate values
}

// NewPoint instaniates a new Point
func NewPoint(a, b *math.Int) *Point {
	return &Point{x: a, y: b}
}

// NewPointFromBytes reconstructs a Point from binary representation.
func NewPointFromBytes(b []byte) (p *Point, compr bool, err error) {
	p = NewPoint(math.ZERO, math.ZERO)
	err = nil
	compr = true
	switch b[0] {
	case 0:
	case 4:
		p.x = math.NewIntFromBytes(b[1:33])
		p.y = math.NewIntFromBytes(b[33:])
		compr = false
	case 3:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 1)
		if err != nil {
			return
{'fraction_non_alphanumeric': 0.12713675213675213, 'fraction_numerical': 0.05641025641025641, 'mean_word_length': 3.630069238377844, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2316369', 'n_tokens_mistral': 2049, 'n_tokens_neox': 1843, 'n_words': 530}