Bitcoin Forum
August 02, 2024, 10:20:07 AM *
News: Latest Bitcoin Core release: 27.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Bitcoin in Perl6  (Read 2230 times)
grondilu (OP)
Legendary
*
Offline Offline

Activity: 1288
Merit: 1076


View Profile
January 26, 2012, 10:14:21 AM
Last edit: February 01, 2012, 12:23:12 PM by grondilu
 #1

I'd like to help implementing Bitcoin in Perl6, one of the most awesome programming language of the future.

Here is the beginning, the Base58 encoding:

Code:
#!/usr/local/bin/perl6
module Bitcoin::Base58;

my @b58 = <
      1 2 3 4 5 6 7 8 9
    A B C D E F G H   J K L M N   P Q R S T U V W X Y Z
    a b c d e f g h i j k   m n o p q r s t u v w x y z
>;
my %b58 = @b58 Z ^58;

our sub decode(Str $x) returns Int { $x ~~ /.$/ ?? %b58{$/} + 58*&?ROUTINE($/.prematch) !! 0 }
our sub encode(Int $n) returns Str { $n < 58 ?? @b58[$n] !! &?ROUTINE($n div 58) ~ @b58[$n%58] }

More will come.

grondilu (OP)
Legendary
*
Offline Offline

Activity: 1288
Merit: 1076


View Profile
February 28, 2012, 10:29:00 AM
Last edit: February 29, 2012, 12:03:36 PM by grondilu
 #2

I wrote a Crypto module.  Only Sha256 and rmd160 so far.

Sha256 seems to work fine but rmd160 returns wrong result FIXED

http://s0.barwen.ch/~grondilu/Crypto.pm6

grondilu (OP)
Legendary
*
Offline Offline

Activity: 1288
Merit: 1076


View Profile
May 16, 2012, 08:41:41 AM
Last edit: May 16, 2012, 02:26:01 PM by grondilu
 #3

I created two github repositories:


You can now create addresses in Perl6:

Code:
use Bitcoin; my Bitcoin::Key $key .= new;  .say for $key, $key.address;

Or check an existing key or address:

Code:
use Bitcoin; say Bitcoin::Address.new: "1SomeSi11yAddressToCheckXXXXX";

This is still the most basic stuff and it is awefully slow but there is a begin to everything, right?

This is a very long term project anyway.

da2ce7
Legendary
*
Offline Offline

Activity: 1222
Merit: 1016


Live and Let Live


View Profile
May 16, 2012, 12:52:30 PM
 #4

This is still the most basic stuff and it is awefully slow but there is a begin to everything, right?

This is a very long term project anyway.

Yes!  Perl 6 is shaping to be the best thing since sliced bread!  Smiley

I wish I had more time to help this project... However all my time is going to Open Transactions.

One off NP-Hard.
grondilu (OP)
Legendary
*
Offline Offline

Activity: 1288
Merit: 1076


View Profile
May 25, 2012, 02:16:48 PM
 #5

Lots of improvements.  The Bitcoin::DataStream class is now implemented.  This allows me to create a block object from a hexdump and check its proof-of-work.

However, it requires a customed version of rakudo with more complete pack/unpack functions.  They can be found on my fork of rakudo: http://github.com/grondilu/rakudo

It's still pretty slow, though.  But I love the syntax of the whole thing, for instance for creating a new, random bitcoin address:

Code:
use Bitcoin;
say my $k = Bitcoin::Key.new;
say $k.address;


What is really missing now is a decent database library.  If someone would like to port BerkeleyDB on perl6, it would be awesome.

grondilu (OP)
Legendary
*
Offline Offline

Activity: 1288
Merit: 1076


View Profile
June 06, 2012, 09:16:38 AM
 #6



I found out that a really slow part was the elliptic curve exponentiation (this is needed when converting a private key to a bitcoin address).

So I wrote a wrapper to make it possible to compute this using BC.  It is used when the environment variable "PERL6_EC_METHOD" is set to "BC".   It's now about five times faster.

Here is the bc code:

Code:
/*
 *
 * A small library for elliptic curve arithmetics and cryptography with
 * bitcoin.
 *
 *
 */

scale=0;

/* secp256k1 parameters */
ibase=16;
p= FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
b= 7;
a= 0;
gx=79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;
gy=483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;
go=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
ibase=A;

/* A modulo function that behaves well with negative numbers */
define true_mod(n, m) {
    if (n >= 0) return n%m else return -n*(m-1)%m;
}

/* modular inverse function */
define inverse_mod ( n, m ) {
    auto c, tc, d, td, uc, tuc, vc, tvc, ud, vd, q;
    c = true_mod(n, m); d = m; uc=1; vc=0; ud=0; vd=1; q=0;
    while (c != 0) {
q = d / c;
tc = c;
c = true_mod(d, c);
d = tc;

tuc = uc;
tvc = vc;
uc = ud - q*uc;
vc = vd - q*vc;
ud = tuc;
vd = tvc;
    }
    return true_mod(ud, m);
}

/* This test function should print a long sequence of '1'. */
define test_inverse_mod () {
    auto n, i;
    n = 2017;
    for (i=1; i<n; i++) print (i * inverse_mod(i, n)), n;
}

/*
 * Elliptic curve operations.
 *
 * For simplicity, we'll ignore the possibiliy of a
 * point at horizon.
 *
 * BC functions can not return multiple values,
 * so we'll use a base-p encoding for points.
 *
 */

define add( point_a, point_b ) {
    auto i, l, x, y, xa, ya, xb, yb;
    xa = point_a / p; ya = point_a % p;
    xb = point_b / p; yb = point_b % p;
    i = inverse_mod( xb - xa, p );
    l = true_mod((yb - ya) * i, p);
    x = l^2 - xa - xb;
    y = l*(xa - x) - ya;
    return true_mod(x, p) *p + true_mod(y, p);
}

define double( point ) {
    auto l, x, y, xout, yout;
    x = point / p; y = point % p;
    l = true_mod((3*x^2 + a) * inverse_mod( 2*y, p ), p);
    xout = true_mod(l^2 - 2*x, p);
    yout = true_mod(l*(x - xout) - y, p);
    return xout * p + yout;
}

define mult( k, point ) {
    if (k == 1) return point;
    if (k == 2) return double( point );
    if (k % 2 == 0) return double( mult( k/2, point ) );
    return add(point, double( mult( k/2, point ) ));
}

];

our sub compute(Str $expression) {
    return map {:16($_)},
    qqx[
    echo "{code}
    tmp = $expression;
    obase=16;
    tmp / p
    tmp % p
    quit" |
    bc -q
    ].comb: /<xdigit>+/;
}

MatthewLM
Legendary
*
Offline Offline

Activity: 1190
Merit: 1004


View Profile
June 06, 2012, 02:53:03 PM
 #7

You should note when making the cryptography code that there are some irregularities with OpenSSL which is what bitcoin-qt uses and your code should be compatible with these irregularities. Discussed here: http://bitcoinstats.com/irc/bitcoin-dev/logs/2012/06/05/2#l3670669 It's possible that if you have a client that does not take care of these OpenSSL irregularities then particular public keys and maybe signatures in transactions would be accepted by OpenSSL but not your code. This means bitcoin-qt would accept the transactions as valid but your code wont.

I'm no expert on that though.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!