Skip to content

Instantly share code, notes, and snippets.

@Peilonrayz
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Peilonrayz/10749653 to your computer and use it in GitHub Desktop.
Save Peilonrayz/10749653 to your computer and use it in GitHub Desktop.
This is a very poorly written RSA alg in Rust. This has very few features, and cannot automate p, q or e on it's own. (Randomly)
extern crate rand;
use std::str;
use rand::{task_rng, Rng};
//A few nice Bool funcs.
struct Bool;
impl Bool{
fn not(b: bool) -> bool{if b{false}else{true}}
fn and(a: u64, b: u64) -> u64{a & b}
fn xor(a: u64, b: u64) -> u64{a ^ b}
fn or(a: u64, b: u64) -> u64{a | b}
}
//A few nice uint funcs.
struct Uint;
impl Uint{
fn max(a: uint, b: uint) -> uint{if a>b{a}else{b}}
fn min(a: uint, b: uint) -> uint{if a<b{a}else{b}}
}
//+-----------+
//|Decloration|
//+-----------+
//new new_int new_int_sp new_list new_list_sp new_rnd copy copy_int copy_int_sp copy_list copy_list_sp copy_rnd clone
//(no default arguments, so have a ton).
//Luckily they are 'legit' and hopefully will be added, same with named.
pub fn new() -> Integer{
new_list(~[0u64])
}
pub fn new_int(i: u64) -> Integer{
new_list(~[i])
}
pub fn new_int_sp(i: u64, signed: bool, pos: bool) -> Integer{
new_list_sp(~[i], signed, pos)
}
pub fn new_list(list: ~[u64]) -> Integer{
new_list_sp(list, true, true)
}
pub fn new_list_sp(list: ~[u64], signed: bool, pos: bool) -> Integer{
_new(list, signed, pos)
}
pub fn _new(list: ~[u64], signed: bool, pos: bool) -> Integer{
let mut a: u64 = 1u64;
let mut b: u64 = 0u64;
let mut c: uint = 0u;
while a != b{
b = a;
a = (a << 1) + 1u64;
c += 1;
}
let m1 = 1 << (c-1);
let m2 = m1 - 1;
Integer {list:list, max:a, len:c, signed:signed, pos:pos, m1:m1, m2:m2}
}
fn new_rnd(size: u64) -> Integer{
new()._rnd(size)
}
struct Integer{
list: ~[u64],
max: u64,
len: uint,
signed: bool,
pos: bool,
m1: u64,
m2: u64
}
impl Integer{
//+-----------+
//|Decloration|
//+-----------+
//new new_int new_int_sp new_list new_list_sp copy copy_int copy_int_sp copy_list copy_list_sp clone
//(no default arguments, so have a ton).
//Luckily they are 'legit' and hopefully will be added, same with named.
fn copy(&self) -> Integer{
self.copy_list(~[0u64])
}
fn copy_int(&self, i: u64) -> Integer{
self.copy_list(~[i])
}
fn copy_int_sp(&self, i: u64, signed: bool, pos: bool) -> Integer{
self.copy_list_sp(~[i], signed, pos)
}
fn copy_list(&self, list: ~[u64]) -> Integer{
self.copy_list_sp(list, true, true)
}
fn copy_list_sp(&self, list: ~[u64], signed: bool, pos: bool) -> Integer{
self._copy(list, signed, pos)
}
fn _copy(&self, list: ~[u64], signed: bool, pos: bool) -> Integer{
Integer {list:list, max:self.max, len:self.len, signed:signed, pos:pos, m1:self.m1, m2:self.m2}
}
fn copy_rnd(&self, size: u64) -> Integer{
self._rnd(size)
}
fn _rnd(&self, size: u64) -> Integer{
let mut list: ~[u64] = ~[];
let mut rng = task_rng();
for i in range(0, size){
list = list + ~[rng.gen::<u64>()];
}
self.copy_list(list)
}
fn _clone_list(&self, len: uint) -> ~[u64]{
let mut list: ~[u64] = ~[];
for i in range(0, Uint::min(len, self.list.len())){
list = list + ~[self.list[i]];
}
list
}
fn clone_list(&self) -> ~[u64]{
self._clone_list(self.list.len())
}
fn _extend_list(&self, size: uint) -> ~[u64]{
let mut list = self._clone_list(size);
while list.len() < size{
list = list + ~[if self.pos{0}else{self.max}];
}
list
}
fn clone(&self) -> Integer{
self.copy_list_sp(self.clone_list(), self.signed, self.pos)
}
//+--------------------+
//|Arithmetic operators|
//+--------------------+
//+ - * / % pow pow% sqrt
fn _add(s:u64, o:u64, ca:u64, m1:u64, m2:u64, l:u64) -> (u64, u64){
let a = s&m1;
let b = o&m1;
let cb = (s&m2)+(o&m2);
let c = cb&m1;
let db = (cb&m2)+ca;
let d = db&m1;
let e = a^b;
let f = a&b;
let g = c^d;
let h = c&d;
let i = e^g;
((db&m2)+i, (((f^h)|(e&g))>>l)+(f&h)>>(l-1))
}
fn __add__(&self, other: Integer) -> Integer{
let mut list: ~[u64] = ~[];
let m1: u64 = self.m1;//Are globals slower to look up then locals? If not, remove the locals!
let m2: u64 = self.m2;
let l: u64 = (self.len as u64);
let (l1, l2) = (self.list.len(), other.list.len());
let s: bool = (((self.list[l1-1]&m1) != 0) && (self.pos == false))||(((other.list[l2-1]&m1) != 0) && (other.pos == false));
let m = if l1<l2{l1}else{l2};
let ma = if l1>l2{l1}else{l2};
let mut ca: u64 = 0u64;
for i in range(0, m){
match Integer::_add(self.list[i], other.list[i], ca, m1, m2, l){(t1, t2) => {
list = list + ~[t1];
ca = t2;
} } }
if l1 != l2{
if m == l1{
for i in range(m, ma){
match Integer::_add(0u64, other.list[i], ca, m1, m2, l){(t1, t2) => {
list = list + ~[t1];
ca = t2;
} } }
}else{
for i in range(m, ma){
match Integer::_add(self.list[i], 0u64, ca, m1, m2, l){(t1, t2) => {
list = list + ~[t1];
ca = t2;
} } }
}
}
//println!("s:{}, ca:{}", s, ca)
if Bool::not(s) && ca != 0{//This is not to be used with negatives, or our numbers will allways be negative!
list = list + ~[ca];
}
let boo = if s && ((list[list.len()-1]&m1) != 0){false}else{true};
let out = self.copy_list_sp(list, true, boo);
//println!("{}.__add__{} => new({}, true, {})", self._hex(), other._hex(), out._hex(), boo);
out
}
fn __inv(&self) -> ~[u64]{
let mut list: ~[u64] = ~[];
for i in range(0, self.list.len()){
list = list + ~[self.max - self.list[i]];
}
list
}
fn __inv__(&self) -> Integer{
self.copy_list_sp(self.__inv(), self.signed, if self.signed{if self.pos{false}else{true}}else{false})
}
fn _inv(&self, other: Integer) -> Integer{
let mut a: ~[u64] = self.__inv();
for i in range(self.list.len(), other.list.len()){
a = a + ~[self.max];
}
self.copy_list_sp(a, self.signed, if self.signed{if self.pos{false}else{true}}else{false})
}
fn __sub__(&self, other: Integer) -> Integer{
if self.list.len() > other.list.len(){
self.__add__(other._inv(self.copy()).__add__(self.copy_int(1)))
}else{
self.__add__(other.__inv__().__add__(self.copy_int(1)))
}
}
fn _olen(&self) -> uint{
let mut num: uint = 0u;
for i in range(0, self.list.len()){
let mut a = self.list[i];
while a != 0{
if (a&1)==1{
num += 1;
}
a = a >> 1;
}
}
num
}
fn _mul(small: Integer, big: Integer) -> Integer{
let mut num = big.copy();
let mut small = small;
for i in range(0, big.list.len()){
let mut a = big.list[i];
while a != 0{
if (a&1)==1{num = num.__add__(small.clone());}
a = a >> 1;
small = small._lshift(1, true);
}
}
num
}
fn __mul__(&self, other: Integer) -> Integer{
if self._olen() > other._olen(){
Integer::_mul(self.clone(), other.clone())
}else{
Integer::_mul(other.clone(), self.clone())
}
}
//This function was really annoying! So I put the python code next to it, to check it is right.
fn _div(slf: Integer, other: Integer) -> (Integer, Integer){//def div(n, m):
let max = Uint::max(slf.list.len(), other.list.len()); //
let mut t = other.copy_list(other._extend_list(max+1u));// t = m
let mut q = slf.copy_list(new()._extend_list(max)); // q = 0
let mut r = slf.copy_list(slf._extend_list(max)); // r = n
while t.__le__(r.clone()){ // while t <= n:
t = t.__lshift__(1); // t <<= 1
} //
let mut t = t.copy_list(t._extend_list(max)); //
t = t.__rshift__(1); // t >>= 1
while t.__ge__(other.clone()){ // while t >= m:
q = q.__lshift__(1); // q <<= 1
if t.__le__(r.clone()){ // if t <= r:
q = q.__add__(slf.copy_int(1)); // q = q + 1
r = r.__sub__(t.clone()); // r = r - t
} //
t = t.__rshift__(1); // t >>= 1
} //
(q, r) // return q, r
}
fn __div__(&self, other: Integer) -> Integer{
let (a, b) = Integer::_div(self.clone(), other);
a
}
fn __mod__(&self, other: Integer) -> Integer{
let (a, b) = Integer::_div(self.clone(), other);
b
}
fn __mod2__(&self) -> bool{//i % 2 == 0
self.__and__(self.copy_int(1)).__eq__(self.copy())
}
fn __pow__(&self, other: Integer) -> Integer{
if other.__lt__(self.copy()) {return self.copy_int(if self.__eq__(self.copy_int(1)){1}else{0});}
if other.__eq__(self.copy()) {return self.copy_int(1);}
if other.__eq__(self.copy_int(1)) {return self.clone();}
if other.__mod2__(){
self.copy_int(1)
}else{
self.clone()
}.__mul__( self.__mul__(self.clone()).__pow__(other.__rshift__(1)) )
}
fn _powm(slf: Integer, other: Integer, ret: Integer) -> Integer{
let mut c = slf.copy_int(1);
let mut b = slf.__mod__(ret.clone());
let mut e = other;
while e.__ne__(slf.copy()){
if e.__mod2__(){
c = c.__mul__(b.clone()).__mod__(ret.clone());
}
e = e.__rshift__(1);
b = b.__mul__(b.clone()).__mod__(ret.clone());
}
c
}
fn __powm__(&self, other: Integer, ret: Integer) -> Integer{
Integer::_powm(self.clone(), other, ret)
}
//This is probably not the least bit acurate.
//This is to get closer then self/2 to the real sqrt.
fn __sqrt__(&self) -> Integer{
let a = self.clone();
let mut x = self.copy_int(1);
let mut x2 = self.copy_int(1);
while true{
x2 = x.__add__(a.clone().__div__(x.clone())).__div__(self.copy_int(2));
if x2.__sub__(x.clone()).__lt__(self.copy_int(1)){break;}
x = x2
}
x
}
//+-----------------+
//|Bitwise operators|
//+-----------------+
//<< >> & ^ |
fn _lshift(&self, a: int, cb: bool) -> Integer{
let aa: u64 = if a%64!=0{a as u64}else{0u64};
let b: u64 = (64u64 - aa);
let mask: u64 = ((1u64<<aa)-1u64) << b;
let mut c: u64 = 0u64;
let mut list: ~[u64] = ~[];
let d = (a/64)as uint;
if d < self.list.len(){
for i in range(0, self.list.len()-d){
list = list + ~[((self.list[i]<<aa))|c];
c = (mask & self.list[i])>>b;
}
if cb{list = list + ~[c];}
}
for i in range(0, d){
list = ~[0u64] + list;
}
self.copy_list(list)
}
fn __lshift__(&self, a: int) -> Integer{
self._lshift(a, false)
}
fn __rshift__(&self, a: int) -> Integer{
let aa: u64 = if a%64!=0{a as u64}else{0u64};
let b: u64 = (64u64 - aa);
let mask: u64 = ((1u64<<aa)-1u64);
let mut c: u64 = 0u64;
let mut list: ~[u64] = ~[];
let d = (a/64)as uint;
if d < self.list.len(){
for i in range(0, self.list.len()-1-d){
c = (mask & self.list[i+d+1])<<b;
list = list + ~[((self.list[i]>>aa))|c];
}
list = list + ~[((self.list[self.list.len()-1]>>aa))];
}
for i in range(0, d){
list = list + ~[0u64];
}
self.copy_list(list)
}
fn _gate(&self, other: Integer, func: fn(u64, u64)->u64) -> Integer{
let mut list: ~[u64] = ~[];
let (l1, l2) = (self.list.len(), other.list.len());
let m = if l1<l2{l1}else{l2};
let ma = if l1>l2{l1}else{l2};
for i in range(0, m){
list = list + ~[func(self.list[i], other.list[i])];
}
if l1 != l2{
if l1 == m{
for i in range(0, m){
list = list + ~[func(0u64, other.list[i])];
}
}else{
for i in range(0, m){
list = list + ~[func(self.list[i], 0u64)];
}
}
}
self.copy_list(list)
}
fn __and__(&self, other: Integer) -> Integer{
self._gate(other, Bool::and)
}
fn __xor__(&self, other: Integer) -> Integer{
self._gate(other, Bool::xor)
}
fn __or__(&self, other: Integer) -> Integer{
self._gate(other, Bool::or)
}
//+--------------------+
//|Comparison operators|
//+--------------------+
//< > == != >= <=
fn __lt__(&self, other: Integer) -> bool{
if (self.pos == false) && other.pos{return true;}
let m = Uint::max(self.list.len(), other.list.len());
let a = self.copy_list(self._extend_list(m));
let b = other.copy_list(other._extend_list(m));
let mut n = 0;
for i in range(0, m){
if a.list[m-1-i] != 0 || b.list[m-1-i] != 0{
n = i;
break;
}
}
let boo =
if a.list[m-1-n] >= b.list[m-1-n]{
false
}else{
true
};
//println!("{} < {} => {}", self._hex(), other._hex(), boo);
boo
}
fn __le__(&self, other: Integer) -> bool{self.__eq__(other.clone())||self.__lt__(other.clone())}
fn __eq__(&self, other: Integer) -> bool{
let boo =
//if self.list.len() != other.list.len(){ false
//}else
if self.pos != other.pos{ false
}else{
let m = Uint::max(self.list.len(), other.list.len());
let a = self.copy_list(self._extend_list(m));
let b = other.copy_list(other._extend_list(m));
let mut n: bool = true;
for i in range(0, m){
if a.list[i] != b.list[i]{
n = false;
break;
}
}
n
};
//println!("{} == {} => {}", self._hex(), other._hex(), boo);
boo
}
fn __ne__(&self, other: Integer) -> bool{Bool::not(self.__eq__(other))}
fn __gt__(&self, other: Integer) -> bool{Bool::not(self.__lt__(other.clone())) && self.__ne__(other)}
fn __ge__(&self, other: Integer) -> bool{Bool::not(self.__lt__(other))}
fn __prime__(&self) -> bool{
if self.__lt__(self.copy_int(2)) {return false;}
if self.__le__(self.copy_int(3)) {return true;}
if self.__mod__(self.copy_int(2)).__eq__(self.copy())
|| self.__mod__(self.copy_int(3)).__eq__(self.copy()) {return false;}
//let max = self.__sqrt__();
let max = self.__div__(self.copy_int(2));
let mut div = self.copy_int(5);
let two = self.copy_int(2);
let six = self.copy_int(6);
while div.__le__(max.clone()){
if self.__mod__(div.clone()).__eq__(self.copy())
|| self.__mod__(div.__add__(two.clone())).__eq__(self.copy()){return false;}
div = div.__add__(six.clone())
}
true
}
//+-----+
//|Other|
//+-----+
//bin hex print copy
//dec is problematic 64/log[2](10) = 19.27... cba to fix that!
//These should be removed after finishing 'integer'.
//Unless people want to be able to print in bin, or hex.
fn _bin(&self) -> ~str{
Int::to_base(self.clone_list(), Int::to_bin, ~"0b", self.len)
}
fn bin(&self) -> ~str{
Int::to_base(self.clone_list(), Int::to_bin, ~"", self.len)
}
fn pbin(&self){
println!("{}", self._bin());
}
fn _hex(&self) -> ~str{
Int::to_base(self.clone_list(), Int::to_hex, ~"0x", self.len/4)
}
fn hex(&self) -> ~str{
Int::to_base(self.clone_list(), Int::to_hex, ~"", self.len/4)
}
fn phex(&self){
println!("{}", self._hex());
}
fn toint(&self) -> ~[i64]{
let mut list: ~[i64] = ~[];
for i in range(0, self.list.len()){
list = list + ~[self.list[i]as i64];
}
list
}
fn get(&self){
if self.signed && (self.pos == false){
println!("The numbers are: {}", self.toint());
}else{
println!("The numbers are: {}", self.list);
}
}
fn _get(&self){
println!("The numbers are: {}", self.list);
}
}
//These are for seeing changes in the binary easaly.
//*
struct Str;
impl Str{
fn prepend(a: ~str, b: ~str) -> ~str{a + b}
fn append(a: ~str, b: ~str) -> ~str{b + a}
fn padding(string: ~str, pad: ~str, size: uint, func1: fn(~str, ~str) -> ~str, func2: fn(~str, ~str) -> ~str) -> ~str{
if string.len() < size{
let mut ret = ~"";
for i in range(0, size-string.len()){
ret = func1(~"0", ret);
}
return func2(ret, string);
}
string
}
}
struct Int;
impl Int{
fn alph() -> ~str {~"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"}
fn alpi(num: u64) -> ~str{str::from_utf8(&[Int::alph()[num]]).unwrap().to_owned()}
fn _to_base(a: u64, len: uint, amount: u64) -> ~str{
let mut a = a;
let mut string = ~"";
let am = (1<<amount)-1;
while a != 0{
string = Str::prepend(Int::alpi(a&am), string);
a = a >> amount;
}
Str::padding(string, ~"0", len, Str::prepend, Str::prepend)
}
fn to_bin(a: u64, len: uint) -> ~str{
Int::_to_base(a, len, 1)
}
fn to_hex(a: u64, len: uint) -> ~str{
Int::_to_base(a, len, 4)
}
fn to_base(list: ~[u64], func: fn(u64, uint) -> ~str, pre: ~str, len: uint) -> ~str{
let mut string = ~"";
for i in range(0, list.len()){
string = Str::prepend(func(list[i], len), string);
}
Str::prepend(pre, string)
}
fn _from_base(a: ~str, amount: u64) -> u64{
let mut num: u64 = 0;
for i in range(0, a.len()){
let n: &[u8] = &[a[i]];
num = (num << amount) + (Int::alph().find_str(str::from_utf8(n).unwrap()).unwrap() as u64);
}
num
}
fn from_bin(a: ~str) -> u64{
Int::_from_base(a, 1)
}
fn from_hex(a: ~str) -> u64{
Int::_from_base(a, 4)
}
fn from_base(string: ~str, func: fn(~str) -> u64, len: uint) -> ~[u64]{
let mut list: ~[u64] = ~[];
for i in range(0, string.len()/len){
list = ~[func(string.slice(i*len, (i+1u)*len).to_owned())] + list;
}
list
}
fn hex(string: ~str) -> ~[u64]{
Int::from_base(string, Int::from_hex, 16)
}
fn bin(string: ~str) -> ~[u64]{
Int::from_base(string, Int::from_bin, 64)
}
}
//*/
//end of ease of veiwing.
//Should have it's own file, but I can't get it to work...
//*
fn modular_integers(a: Integer, n: Integer) -> Integer{
//println!("a:{}, n:{}", a._hex(), n._hex());
let mut t = new();
let mut newt = new_int(1);
let mut r = n.clone();
let mut newr = a.clone();
let mut q;
//println!("start while");
//println!("{} != {} == {}", newr._hex(), new()._hex(), newr.__ne__(new()));
while newr.__ne__(new()){
//println!("{} / {}", r._hex(), newr._hex());
q = r.__div__(newr.clone());
//q.get();
//println!("{}", q._hex());
//break;
//I've forgotton how to use a temp variable, so might as well use a match.
match (newt.clone(), t.__sub__(q.__mul__(newt))) {(a, b) => {t = a; newt = b;}};
match (newr.clone(), r.__sub__(q.__mul__(newr))) {(a, b) => {r = a; newr = b;}};
//println!("{} {} {} {}", newt._hex(), t._hex(), newr._hex(), r._hex());
}
if t.__lt__(new()){t = t.__add__(n.clone());}
if r.__gt__(new_int(1)) {
t = new_int_sp(-1, true, false);
}
t
}
fn make() -> (Integer, Integer, Integer) {
make_e(new())
}
fn make_e(e:Integer) -> (Integer, Integer, Integer) {
let p = new_rnd(2);//2048 bits = 32
let q = new_rnd(2);
//let p = new_int(61);
//let q = new_int(53);
//p.phex();
//q.phex();
let n = p.__mul__(q.clone());
//n.phex();
let phi_n = p.__sub__(new_int(1)).__mul__(q.__sub__(new_int(1)));
//phi_n.phex();
let e =
if e.__lt__(new_int(65537)) {
//let e = getNumber(phi_n);//Need to make a prime that is between 65537 and min(phi_n, 2^256). pref bellow 2^64.
new_int(65537)
}else{
e;
new_int(65537)
};
//e.phex();
let d = modular_integers(e.clone(), phi_n);
//d.phex();
let d = if d.__lt__(new_int(0)) {
new_int_sp(-1, true, false)//Should probably use a diffrent function here, but the current function shouldn't fail.
}else{
d
};
//d.phex();
(n.clone(), e.clone(), d.clone())
}
fn ed_numbers(numbers: ~[Integer], exp: Integer, rem: Integer) -> ~[Integer]{
let mut nums: ~[Integer] = ~[];
for i in range(0, numbers.len()){
let temp: Integer = numbers[i].__powm__(exp.clone(), rem.clone());
//nums = nums + ~[temp];
}
nums
}
//*/
fn add_test(){
let a = new_int(-1);
let b = new_int(1);
a.__add__(b).get();
}
fn sub_test(){
let a = new_int(-1);
let b = new_int(1);
a.__sub__(b).get();
}
fn mul_test(){
let a = new_int(-1);
let b = new_int(2);
//a.phex();
//b.phex();
let c = a.__mul__(b);
c.get();
//c.phex();
}
fn dev_test(){
let a = new_int(21);
let b = new_int(2);
match Integer::_div(a, b){
(a, b) => {
a.get();
b.get();
}
};
}
fn main(){
/*
let (n, e, d) = make();
n.get();
e.get();
d.get();
*/
/*
let num = new();
let max = 10000;
for i in range(1, max){
for j in range(1, max){
num.copy_int(i as u64).__add__(num.copy_int(j as u64));
}
}
*/
/*
add_test();
sub_test();
mul_test();
dev_test();
*/
/*
let a = new_list(~[-1, -1, 0, 0, 0, 0, 0]);
let b = new_list(~[-1, -1, 0, 0, 0, 0, 0]);
a.phex();
b.phex();
let c = a.__mul__(b);
c.phex();
*/
let a = new_int(2147483647);
println!("{}", a.__prime__());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment