-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fp: montgomery reduction #47
Comments
Refactors the interface into a "two phase" initialization. A field can be constructed as an object first, and then an avo context can be provided later (creating a Builder). Now the avo context is a struct field instead of provided as an argument to every function. The motivation here is it will allow addtional state to be stored alongside the context, for example initialized global data sections. This will be useful for the implementation of Montgomery fields. Updates #47
ImplementationAddition
https://github.com/golang/go/blob/05e77d41914d247a1e7caf37d7125ccaa5a53505/src/crypto/elliptic/p256_asm_amd64.s#L1685-L1704 MultiplicationAs a first pass we will implement this with
The main loop of Montgomery reduction is as follows:
Here
An improvement to come later is interleaving multiplication and reduction steps. One benefit of this simpler implementation for now is that the same reduction code can be used for squaring too. |
Currently battling with register allocation failures. Just to make sure it doesn't get lost, here's an adhoc program I'm using to help debug the issue. package main
import (
"fmt"
"log"
"github.com/mmcloughlin/avo/ir"
"github.com/mmcloughlin/avo/operand"
"github.com/mmcloughlin/avo/pass"
"github.com/mmcloughlin/avo/reg"
"github.com/mmcloughlin/ec3/asm/fp/mont"
"github.com/mmcloughlin/ec3/gen/fp"
"github.com/mmcloughlin/ec3/prime"
)
func main() {
cfg := fp.Config{
Field: mont.New(prime.NISTP256),
InverseChain: nil,
PackageName: "p256",
ElementTypeName: "Elt",
}
// Build asm functions.
asm := fp.NewAsm(cfg)
asm.Mul()
ctx := asm.Context()
f, err := ctx.Result()
if err != nil {
log.Fatal(err)
}
// Run compilation passes up to liveness.
passes := pass.Concat(
pass.FunctionPass(pass.LabelTarget),
pass.FunctionPass(pass.CFG),
pass.FunctionPass(pass.Liveness),
)
if err := passes.Execute(f); err != nil {
log.Fatal(err)
}
// Inspect.
debug(f)
}
func debug(f *ir.File) {
for _, fn := range f.Functions() {
function(fn)
}
}
func function(fn *ir.Function) {
fmt.Printf("function:\t%s\n", fn.Name)
for _, inst := range fn.Instructions() {
fmt.Printf("%s\n", inst.Opcode)
fmt.Printf("\tinputs:")
operands(inst.Inputs)
fmt.Printf("\n")
fmt.Printf("\toutputs:")
operands(inst.Outputs)
fmt.Printf("\n")
fmt.Printf("\tlivein:")
registers(inst.LiveIn)
fmt.Printf("\n")
fmt.Printf("\tliveout:")
registers(inst.LiveIn)
fmt.Printf("\n")
}
}
func operands(ops []operand.Op) {
for _, op := range ops {
fmt.Printf(" %s", op.Asm())
}
}
func registers(rs reg.Set) {
for r := range rs {
fmt.Printf(" %s", r.Asm())
}
} Related mmcloughlin/avo#6 |
At first glance, I'm thinking we have a liveness analysis bug. The first instruction in
Digging some more, it seems this variable is a
The others? Well, that was me being dumb and reading from uninitialized registers. Therefore liveness analysis (correctly) marks them as live all the way to the beginning of the function. |
func DebugMontMul(t *testing.T, x, y *big.Int) {
m := new(big.Int).Mul(x, y)
acc := m
for i := uint(0); i < 256; i += 64 {
t.Logf("step %3d: acc = %0129x", i, acc)
// Step 2.1: u_i = x_i * m' (mod b)
u := new(big.Int).Rsh(acc, i)
u.And(u, bigint.Ones(64))
// Step 2.2: x += u_i * m * b^i
u.Mul(u, p)
u.Lsh(u, i)
acc.Add(acc, u)
}
t.Logf(" reduced acc = %0129x", acc)
acc.Rsh(acc, 256)
t.Logf(" shift acc = %0129x", acc)
t.Logf(" cmp p = %d", acc.Cmp(p))
if acc.Cmp(p) >= 0 {
acc.Sub(acc, p)
}
t.Logf(" final acc = %0129x", acc)
} |
Updates mmcloughlin/ec3#47 Extracted-from: mmcloughlin/ec3@c5883e4
Updates mmcloughlin/ec3#47 Extracted-from: mmcloughlin/ec3@6fbf925
Code generator for modular arithmetic using Montgomery reduction.
Example:
crypto/elliptic
P-256.The text was updated successfully, but these errors were encountered: