]> git.cryptolib.org Git - avr-crypto-lib.git/blob - host/bigint_test.rb
initial part of bigint-library; some bugs left
[avr-crypto-lib.git] / host / bigint_test.rb
1 #!/usr/bin/ruby
2 # bigint_test.rb
3 =begin
4     This file is part of the AVR-Crypto-Lib.
5     Copyright (C) 2008, 2009  Daniel Otte (daniel.otte@rub.de)
6
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 =end
20
21 $debug = true
22 $debug = false
23 require 'rubygems'
24 require 'serialport'
25 require 'getopt/std'
26 require 'ftools'
27 require 'date'
28 $buffer_size = 0
29 $conffile_check = Hash.new
30 $conffile_check.default = 0
31
32 ################################################################################
33 # readconfigfile                                                               #
34 ################################################################################
35
36 def readconfigfile(fname, conf)
37   return conf if $conffile_check[fname]==1
38   $conffile_check[fname]=1
39   section = "default"
40   if not File.exists?(fname)
41     return conf
42   end
43   file = File.open(fname, "r")
44   until file.eof
45     line = file.gets()
46         next if /[\s]*#/.match(line)
47         if m=/\[[\s]*([^\s]*)[\s]*\]/.match(line)
48           section=m[1]
49           conf[m[1]] = Hash.new
50           next
51         end
52         next if not /=/.match(line)
53         m=/[\s]*([^\s]*)[\s]*=[\s]*([^\s]*)/.match(line)
54         if m[1]=="include"
55           Dir.glob(m[2]){ |fn| conf = readconfigfile(fn, conf) }
56         else
57           conf[section][m[1]] = m[2]
58         end
59   end
60   file.close()
61   return conf
62 end
63
64 ################################################################################
65 # reset_system                                                                 #
66 ################################################################################
67
68 def reset_system
69   $sp.print("exit\r")
70   sleep 0.1
71   $sp.print("exit\r")
72   sleep 0.1
73 end
74
75 ################################################################################
76 # init_system                                                                  #
77 ################################################################################
78
79 def init_system(test_prog)
80   $sp.print("echo off \r")
81   print("DBG i: " + "echo off \r"+"\n") if $debug
82   sleep 0.1
83   $sp.print("#{test_prog}\r")
84   print("DBG i: " + "#{test_prog} \r"+"\n") if $debug
85   sleep 1
86 end
87
88
89 ################################################################################
90 # screen_progress                                                              #
91 ################################################################################
92 def screen_progress(v)
93   if $linepos==0
94     printf("\n%5d [%04d]: ", $testno, $size)
95   end
96   putc((v)?('*'):('!'))
97   $testno += 1
98   $linepos = ($linepos+1)%$linewidth
99 end
100
101 ################################################################################
102 # add_test                                                                     #
103 ################################################################################
104
105 def add_test(a,b)
106   begin
107     line = $sp.gets()
108     line = "" if line==nil
109     puts("DBG got: "+line) if $debug
110     if /^Error:.*/.match(line)
111       puts line
112       return false
113     end
114   end while not /[\s]*enter a:[\s]*/.match(line)
115   $sp.print(a.to_s(16)+" ")
116   begin
117     line = $sp.gets()
118     line = "" if line==nil
119     puts("DBG got: "+line) if $debug
120     if /^Error:.*/.match(line)
121       puts line
122       return false
123     end
124   end while not /[\s]*enter b:[\s]*/.match(line)
125   $sp.print(b.to_s(16)+" ")
126   begin
127     line = $sp.gets()
128     line = "" if line==nil
129     puts("DBG got: "+line) if $debug
130     if /^Error:.*/.match(line)
131       puts line
132       return false
133     end
134   end while not m=/[\s]*([-]?[0-9a-fA-F]*)[\s]+\+[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
135   a_ = m[1].to_i(16)
136   b_ = m[2].to_i(16)
137   c_ = m[3].to_i(16)
138   line.chomp!
139   if(a_== a && b_ == b && c_ == (a+b))
140     $logfile.printf("[pass]: %s\n", line)
141     return true
142   else
143     $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a+b)?"":"c",line)
144     $logfile.printf(" ; should %s + %s = %s\n", a.to_s(16), b.to_s(16), (a+b).to_s(16))
145     return false
146   end
147   return false
148 end
149
150 ################################################################################
151 # mul_test                                                                     #
152 ################################################################################
153
154 def mul_test(a,b)
155   begin
156     line = $sp.gets()
157     line = "" if line==nil
158     puts("DBG got: "+line) if $debug
159     if /^Error:.*/.match(line)
160       puts line
161       return false
162     end
163   end while not /[\s]*enter a:[\s]*/.match(line)
164   $sp.print(a.to_s(16)+" ")
165   begin
166     line = $sp.gets()
167     line = "" if line==nil
168     puts("DBG got: "+line) if $debug
169     if /^Error:.*/.match(line)
170       puts line
171       return false
172     end
173   end while not /[\s]*enter b:[\s]*/.match(line)
174   $sp.print(b.to_s(16)+" ")
175   begin
176     line = $sp.gets()
177     line = "" if line==nil
178     puts("DBG got: "+line) if $debug
179     if /^Error:.*/.match(line)
180       puts line
181       return false
182     end
183   end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+\*[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
184   a_ = m[1].to_i(16)
185   b_ = m[2].to_i(16)
186   c_ = m[3].to_i(16)
187   line.chomp!
188   if(a_== a && b_ == b && c_ == (a*b))
189     $logfile.printf("[pass]: %s\n", line)
190     return true
191   else
192     $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a+b)?"":"c",line)
193     $logfile.printf(" ; should %s * %s = %s\n", a.to_s(16), b.to_s(16), (a*b).to_s(16))
194     return false
195   end
196   return false
197 end
198
199 ################################################################################
200 # square_test                                                                  #
201 ################################################################################
202
203 def square_test(a)
204   begin
205     line = $sp.gets()
206     line = "" if line==nil
207     puts("DBG got: "+line) if $debug
208     if /^Error:.*/.match(line)
209       puts line
210       return false
211     end
212   end while not /[\s]*enter a:[\s]*/.match(line)
213   $sp.print(a.to_s(16)+" ")
214   begin
215     line = $sp.gets()
216     line = "" if line==nil
217     puts("DBG got: "+line) if $debug
218     if /^Error:.*/.match(line)
219       puts line
220       return false
221     end
222   end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]*\*\*2[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line)
223   a_ = m[1].to_i(16)
224   c_ = m[2].to_i(16)
225   line.chomp!
226   if(a_== a && c_ == (a**2))
227     $logfile.printf("[pass]: %s\n", line)
228     return true
229   else
230     $logfile.printf("[fail (%s%s)]: %s", (a==a_)?"":"a", (c_==a**2)?"":"c",line)
231     $logfile.printf(" ; should %s **2 = %s\n", a.to_s(16), (a**2).to_s(16))
232     return false
233   end
234   return false
235 end
236
237 ################################################################################
238 # run_test_add                                                                 #
239 ################################################################################
240
241 def run_test_add(skip=0)
242   length_a_B = skip+1
243   length_b_B = skip+1
244   begin
245     $size = length_a_B
246     (0..16).each do |i|
247       s_a = rand(2)*2-1
248       s_b = rand(2)*2-1
249       a = rand(256**length_a_B) * s_a
250       b = rand(256**length_a_B) * s_b
251       v = add_test(a, b)
252       screen_progress(v)
253       v = add_test(b, a)
254       screen_progress(v)
255     end
256     (0..16).each do |i|
257       s_a = rand(2)-1
258       s_b = rand(2)-1
259       b_size = rand(length_b_B+1)
260       a = rand(256**length_a_B) * s_a
261       b = rand(256**b_size) * s_b
262       v = add_test(a, b)
263       screen_progress(v)      
264       v = add_test(b, a)
265       screen_progress(v)
266
267     end
268     length_a_B += 1
269     length_b_B += 1
270   end while length_a_B<4096/8
271 end
272
273 ################################################################################
274 # run_test_mul                                                                 #
275 ################################################################################
276
277 def run_test_mul(skip=0)
278   length_a_B = skip+1
279   length_b_B = skip+1
280   begin
281     $size = length_a_B
282     (0..16).each do |i|
283       s_a = rand(2)*2-1
284       s_b = rand(2)*2-1
285       a = rand(256**length_a_B) * s_a
286       b = rand(256**length_a_B) * s_b
287       v = mul_test(a, b)
288       screen_progress(v)
289       v = mul_test(b, a)
290       screen_progress(v)
291     end
292     (0..16).each do |i|
293       s_a = rand(2)-1
294       s_b = rand(2)-1
295       b_size = rand(length_b_B+1)
296       a = rand(256**length_a_B) * s_a
297       b = rand(256**b_size) * s_b
298       v = mul_test(a, b)
299       screen_progress(v)      
300       v = mul_test(b, a)
301       screen_progress(v)
302     end
303     length_a_B += 1
304     length_b_B += 1
305   end while length_a_B<4096/8
306 end
307
308 ################################################################################
309 # run_test_square                                                              #
310 ################################################################################
311
312 def run_test_square(skip=0)
313   length_a_B = skip+1
314   begin
315     $size = length_a_B
316     (0..16).each do |i|
317       a = rand(256**length_a_B)
318       v = square_test(a)
319       screen_progress(v)
320     end
321     length_a_B += 1
322   end while length_a_B<4096/8
323 end
324
325 ################################################################################
326 # MAIN                                                                         #
327 ################################################################################
328
329 opts = Getopt::Std.getopts("s:f:i:a:hd")
330
331 conf = Hash.new
332 conf = readconfigfile("/etc/testport.conf", conf)
333 conf = readconfigfile("~/.testport.conf", conf)
334 conf = readconfigfile("testport.conf", conf)
335 conf = readconfigfile(opts["f"], conf) if opts["f"]
336
337 #puts conf.inspect
338
339 puts("serial port interface version: " + SerialPort::VERSION);
340 $linewidth = 64
341 $linepos = 0
342 $testno = 0
343 params = { "baud"       => conf["PORT"]["baud"].to_i,
344             "data_bits" => conf["PORT"]["databits"].to_i,
345             "stop_bits" => conf["PORT"]["stopbits"].to_i,
346             "parity"    => SerialPort::NONE }
347 params["paraty"] = SerialPort::ODD   if conf["PORT"]["paraty"].downcase == "odd"
348 params["paraty"] = SerialPort::EVEN  if conf["PORT"]["paraty"].downcase == "even"
349 params["paraty"] = SerialPort::MARK  if conf["PORT"]["paraty"].downcase == "mark"
350 params["paraty"] = SerialPort::SPACE if conf["PORT"]["paraty"].downcase == "space"
351
352 puts("\nPort: "+conf["PORT"]["port"]+"@"    +
353                 params["baud"].to_s      +
354                 " "                      +
355                 params["data_bits"].to_s +
356                 conf["PORT"]["paraty"][0,1].upcase +
357                 params["stop_bits"].to_s +
358                 "\n")
359
360 $sp = SerialPort.new(conf["PORT"]["port"], params)
361
362 $sp.read_timeout=1000; # 5 minutes
363 $sp.flow_control = SerialPort::SOFT
364
365 reset_system()
366
367 if opts['d']
368   $debug = true
369 end
370
371 logfilename = conf['PORT']['testlogbase']+'bigint.txt'
372 if File.exists?(logfilename)
373   i=1
374   begin
375     logfilename = sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i,'.txt')
376     i+=1
377   end while(File.exists?(logfilename))
378   while(i>2) do
379     File.move(sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-2,'.txt'), 
380               sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',i-1,'.txt'), true)
381     i-=1
382   end
383     File.move(sprintf('%s%s', conf['PORT']['testlogbase'],'bigint.txt'), 
384               sprintf('%s%04d%s', conf['PORT']['testlogbase']+'bigint_',1,'.txt'), true)
385   logfilename = conf['PORT']['testlogbase']+'bigint.txt' 
386 end
387 $logfile = File.open(logfilename, 'w')
388 printf("logfile: %s\n", logfilename)
389
390 $logfile.printf("bigint test from: %s\n", Time.now.to_s)
391 $logfile.printf("skip = %s\n", opts['s']) if opts['s']
392 $logfile.printf("seed = 0x%X\n", 0xdeadbeef)
393
394 tests = Hash.new
395 tests['a'] = proc {|x| run_test_add(x) }
396 tests['m'] = proc {|x| run_test_mul(x) }
397 tests['s'] = proc {|x| run_test_square(x) }
398 init_str = Hash.new
399 init_str['a'] = 'add-test'
400 init_str['m'] = 'mul-test'
401 init_str['s'] = 'square-test'
402
403 srand(0xdeadbeef)
404
405 if opts['a']
406   opts['a'].each_char do |x|
407     if tests[x]
408       puts init_str[x]
409       init_system(init_str[x])
410       tests[x].call(opts['s']?opts['s'].to_i():0) 
411     else
412       puts "no test defiened for '#{x}'"
413     end  
414   end
415 else
416   'ams'.each_char do |x|
417     if tests[x]
418       puts init_str[x]
419       init_system(init_str[x])
420       tests[x].call(opts['s']?opts['s'].to_i():0) 
421     else
422       puts "no test defiened for '#{x}'"
423     end  
424   end
425 end
426
427
428 $logile.close()