From ea44143cf2290e887c16fc7e1f9fa6a0e084fcbd Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 31 Mar 2021 20:16:17 +0200 Subject: Paper rework WIP for submission to CHES'21 --- doc/paper/CC-by.eps | 2727 ++++++++++++++++++++++++++++ doc/paper/CC-by.pdf | Bin 0 -> 4153 bytes doc/paper/iacrtrans.cls | 448 +++++ doc/paper/ihsm_shaft_countermeasures_a.pdf | Bin 0 -> 1486 bytes doc/paper/ihsm_shaft_countermeasures_a.svg | 160 ++ doc/paper/ihsm_shaft_countermeasures_b.pdf | Bin 0 -> 1597 bytes doc/paper/ihsm_shaft_countermeasures_b.svg | 174 ++ doc/paper/ihsm_shaft_countermeasures_c.pdf | Bin 0 -> 1806 bytes doc/paper/ihsm_shaft_countermeasures_c.svg | 246 +++ doc/paper/rotohsm_paper.pdf | Bin 1194057 -> 1580897 bytes doc/paper/rotohsm_paper.tex | 608 ++++--- doc/paper/rotohsm_tech_report.pdf | Bin 112812 -> 112534 bytes 12 files changed, 4082 insertions(+), 281 deletions(-) create mode 100755 doc/paper/CC-by.eps create mode 100755 doc/paper/CC-by.pdf create mode 100755 doc/paper/iacrtrans.cls create mode 100755 doc/paper/ihsm_shaft_countermeasures_a.pdf create mode 100755 doc/paper/ihsm_shaft_countermeasures_a.svg create mode 100755 doc/paper/ihsm_shaft_countermeasures_b.pdf create mode 100755 doc/paper/ihsm_shaft_countermeasures_b.svg create mode 100755 doc/paper/ihsm_shaft_countermeasures_c.pdf create mode 100755 doc/paper/ihsm_shaft_countermeasures_c.svg (limited to 'doc/paper') diff --git a/doc/paper/CC-by.eps b/doc/paper/CC-by.eps new file mode 100755 index 0000000..ae05c8b --- /dev/null +++ b/doc/paper/CC-by.eps @@ -0,0 +1,2727 @@ +%!PS-Adobe-3.0 EPSF-3.0 %%Creator: Adobe Illustrator(R) 8.0 %%AI8_CreatorVersion: 13.0.1 %%For: (Alex Roberts) () %%Title: (by.eps) %%CreationDate: 3/27/08 4:25 PM %%BoundingBox: 360 291 441 307 %%HiResBoundingBox: 360.4727 291.9463 440.5146 306.9878 %%DocumentProcessColors: Cyan Magenta Yellow Black %%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0 %%+ procset Adobe_ColorImage_AI6 1.3 0 %%+ procset Adobe_Illustrator_AI5 1.3 0 %%+ procset Adobe_cshow 2.0 8 %%+ procset Adobe_shading_AI8 1.0 0 %AI5_FileFormat 4.0 %AI3_ColorUsage: Color %AI3_IncludePlacedImages %AI7_ImageSettings: 1 %%CMYKProcessColor: 0.74902 0.678431 0.670588 0.901961 ([Registration]) %%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) %%+ Options: 1 16 0 1 1 1 0 0 0 0 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 2 3 4 %%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 -1 -1 () %AI3_Cropmarks: 360.5 292 440.5 307 %AI3_TemplateBox: 400.5 299.5 400.5 299.5 %AI3_TileBox: 112 -56 688 678 %AI3_DocumentPreview: Macintosh_ColorPic %AI5_ArtSize: 800 600 %AI5_RulerUnits: 6 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI8_OpenToView: -381 756 1 1566 923 26 0 0 73 75 0 0 %AI5_OpenViewLayers: 7 %%PageOrigin:0 0 %AI7_GridSettings: 48 8 48 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %AI7_Thumbnail: 128 24 8 %%BeginData: 3634 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C4527FD80F82752522752525227FD07522752525227FD075227525252 %27FD5D52F8F8F852FD7CFF52F8F852FFFD087D52F8F8F852A8FD07FF5227 %F8F827FD077DFD58F827FF27F8F852FF7D7D7D83FD047DF8F8F8A8FD0AFF %A852F8F827A87D7D7D837D52FD57F827FF52F8F852FFFD077DF8F8F8A8FD %0DFF52F8F827A77D7D7D837DFD58F8FF52F8F852FF7D837D7D7DA827F8F8 %A8FD0FFF52F8F852A87D7D7DA852FD56F827FF52F8F852FFFD057D52F8F8 %52FD08FFA8FD07FFA8F8F827FD067DFD04F8277D527D525227F8277D5227 %F8F8F8525252FD41F8FF52F8F852FF7D837D837D52F827FD04FF7D52527D %FFFFFF7D27527DFFFFFF52F8F87D7D837DA77D27F8F8F852FD06FF7D27FF %FFA8F8F852FFFF7DFD40F827FF52F8F852FFFD057DF8F852FFFFFF27FD04 %F852A827FD04F827FFFFA8F8F852837D7D7DA82DF8F8F852FFFF52F87DFF %FFF852FFFF52F8A8FF7DFD42F8FF52F8F852FF7D7D7DA77DF8F87DFFFF52 %F8F8A8A827527DF827A8FF2752FFFFFF27F8527D837D7D7D58F8F8F852FF %FF27F87DFFFF27F8A8FFFFA8FFFF27FD41F827FF52F8F852FFFD057DF8F8 %7DFFFF27F87DFD04FF27F852FD07FFF8F82783FD047D52F8F8F827FD06FF %52F8F8F8FD04FF52FD43F8FF27F8F852FF7D837DA858F8F8A8FFFF27F852 %FD04FF52F87DFD07FF27F8527D837D837D7DF8F8F852FFFF7DA8A8FFA827 %F8F827FFFFA8FD43F827FF52F8F852FFFD057DF8F87DFFFF52F827A8FF27 %5252F8F8A8A82727FFFFFFF8F82783FD047D52F8F8F827FFFF27F827FFFF %7DF8F827A8FF52FD44F8FF52F8F852FF7D837D7D7D27F852FFFFA827FD04 %F827FF27FD04F827FFFFA8F8F8587D7D7D837D52F8F8F852FFFF522752FF %FF7DF8F827FFFF7DFD43F827FF52F8F852FFFD057D27F8F8FFFFFFA85227 %527DFFFFFF5227277DFFFFFF7DF8F852FD047D8327F8F8F852FD07FFF8F8 %F827FFFF52FD44F8FF52F8F852FF7D837D837D7DF8F852FD11FFF8F827A8 %7D837DA87D27F8F8F827FD067DFD05F87D7D52FD43F827FF52F8F852FFFD %067D27F8F87DFD0FFF27F8F858FD057D52FD57F8FF52F8F852FF7D7D7D83 %7D8358F8F827A8FD0DFF52F8F8527D7D7D837D7DFD57F827FF52F8F852FF %FD077D52F8F8F87DFD0AFFA827F8F827FD057D8327FD58F8FF27F8F852FF %7D837DA87D837DA85227F8F852A8FD07FF7DF8F8F8277DA87D837DA85827 %F827F827F827F827F827F827F827F827F827F827F827F827F827F827F827 %F827F827F827F827F827F827F827F827F827F827F827F827F827F827F827 %F827F827F827F827F827F827F827F827F827F827F827F827F827F827FF52 %F8F852FD0CFFA8FFA8FD07FFA8FFA8FD63FF52F8F827FD7C5227FD80F8F8 %%EndData %%EndComments %%BeginProlog %%BeginResource: procset Adobe_level2_AI5 1.2 0 +%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation) +%%Version: 1.2 0 +%%CreationDate: (04/10/93) () +%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved) +userdict /Adobe_level2_AI5 26 dict dup begin + put + /packedarray where not + { + userdict begin + /packedarray + { + array astore readonly + } bind def + /setpacking /pop load def + /currentpacking false def + end + 0 + } if + pop + userdict /defaultpacking currentpacking put true setpacking + /initialize + { + Adobe_level2_AI5 begin + } bind def + /terminate + { + currentdict Adobe_level2_AI5 eq + { + end + } if + } bind def + mark + /setcustomcolor where not + { + /findcmykcustomcolor + { + (AI8_CMYK_CustomColor) + 6 packedarray + } bind def + /findrgbcustomcolor + { + (AI8_RGB_CustomColor) + 5 packedarray + } bind def + /setcustomcolor + { + exch + aload pop dup + (AI8_CMYK_CustomColor) eq + { + pop pop + 4 + { + 4 index mul + 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } + { + dup (AI8_RGB_CustomColor) eq + { + pop pop + 3 + { + 1 exch sub + 3 index mul + 1 exch sub + 3 1 roll + } repeat + 4 -1 roll pop + setrgbcolor + } + { + pop + 4 + { + 4 index mul 4 1 roll + } repeat + 5 -1 roll pop + setcmykcolor + } ifelse + } ifelse + } + def + } if + /setAIseparationgray + { + false setoverprint + 0 setgray + /setseparationgray where{ + pop setseparationgray + }{ + /setcolorspace where{ + pop + [/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace + 1 exch sub setcolor + }{ + setgray + }ifelse + }ifelse + } def + + /gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def + userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put + userdict /level2? + systemdict /languagelevel known dup + { + pop systemdict /languagelevel get 2 ge + } if + put +/level2ScreenFreq +{ + begin + 60 + HalftoneType 1 eq + { + pop Frequency + } if + HalftoneType 2 eq + { + pop GrayFrequency + } if + HalftoneType 5 eq + { + pop Default level2ScreenFreq + } if + end +} bind def +userdict /currentScreenFreq + level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put +level2? not + { + /setcmykcolor where not + { + /setcmykcolor + { + exch .11 mul add exch .59 mul add exch .3 mul add + 1 exch sub setgray + } def + } if + /currentcmykcolor where not + { + /currentcmykcolor + { + 0 0 0 1 currentgray sub + } def + } if + /setoverprint where not + { + /setoverprint /pop load def + } if + /selectfont where not + { + /selectfont + { + exch findfont exch + dup type /arraytype eq + { + makefont + } + { + scalefont + } ifelse + setfont + } bind def + } if + /cshow where not + { + /cshow + { + [ + 0 0 5 -1 roll aload pop + ] cvx bind forall + } bind def + } if + } if + cleartomark + /anyColor? + { + add add add 0 ne + } bind def + /testColor + { + gsave + setcmykcolor currentcmykcolor + grestore + } bind def + /testCMYKColorThrough + { + testColor anyColor? + } bind def + userdict /composite? + 1 0 0 0 testCMYKColorThrough + 0 1 0 0 testCMYKColorThrough + 0 0 1 0 testCMYKColorThrough + 0 0 0 1 testCMYKColorThrough + and and and + put + composite? not + { + userdict begin + gsave + /cyan? 1 0 0 0 testCMYKColorThrough def + /magenta? 0 1 0 0 testCMYKColorThrough def + /yellow? 0 0 1 0 testCMYKColorThrough def + /black? 0 0 0 1 testCMYKColorThrough def + grestore + /isCMYKSep? cyan? magenta? yellow? black? or or or def + /customColor? isCMYKSep? not def + end + } if + end defaultpacking setpacking +%%EndResource +%%BeginProcSet: Adobe_ColorImage_AI6 1.3 0 +userdict /Adobe_ColorImage_AI6 known not +{ + userdict /Adobe_ColorImage_AI6 53 dict put +} if +userdict /Adobe_ColorImage_AI6 get begin +/initialize { + Adobe_ColorImage_AI6 begin + Adobe_ColorImage_AI6 { + dup type /arraytype eq { + dup xcheck { + bind + } if + } if + pop pop + } forall +} def +/terminate { end } def +currentdict /Adobe_ColorImage_AI6_Vars known not { + /Adobe_ColorImage_AI6_Vars 41 dict def +} if +Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /_newproc null def + /_proc1 null def + /_proc2 null def + /sourcearray 4 array def + /_ptispace null def + /_ptiname null def + /_pti0 0 def + /_pti1 0 def + /_ptiproc null def + /_ptiscale 0 def + /_pticomps 0 def + /_ptibuf 0 string def + /_gtigray 0 def + /_cticmyk null def + /_rtirgb null def + /XIEnable true def + /XIType 0 def + /XIEncoding 0 def + /XICompression 0 def + /XIChannelCount 0 def + /XIBitsPerPixel 0 def + /XIImageHeight 0 def + /XIImageWidth 0 def + /XIImageMatrix null def + /XIRowBytes 0 def + /XIFile null def + /XIBuffer1 null def + /XIBuffer2 null def + /XIBuffer3 null def + /XIDataProc null def + /XIColorSpace /DeviceGray def + /XIColorValues 0 def + /XIPlateList false def +end +/ci6colorimage /colorimage where {/colorimage get}{null} ifelse def +/ci6image systemdict /image get def +/ci6curtransfer systemdict /currenttransfer get def +/ci6curoverprint /currentoverprint where {/currentoverprint get}{{_of}} ifelse def +/ci6foureq { + 4 index ne { + pop pop pop false + }{ + 4 index ne { + pop pop false + }{ + 4 index ne { + pop false + }{ + 4 index eq + } ifelse + } ifelse + } ifelse +} def +/ci6testplate { + Adobe_ColorImage_AI6_Vars begin + /plateindex -1 def + /setcmykcolor where { + pop + gsave + 1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub + 0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub + grestore + 1 0 0 0 ci6foureq { + /plateindex 0 def + }{ + 0 1 0 0 ci6foureq { + /plateindex 1 def + }{ + 0 0 1 0 ci6foureq { + /plateindex 2 def + }{ + 0 0 0 1 ci6foureq { + /plateindex 3 def + }{ + 0 0 0 0 ci6foureq { + /plateindex 5 def + } if + } ifelse + } ifelse + } ifelse + } ifelse + pop pop pop pop + } if + plateindex + end +} def +/ci6concatprocs { + /packedarray where { + pop dup type /packedarraytype eq 2 index type + /packedarraytype eq or + }{ + false + } ifelse + { + /_proc2 exch cvlit def + /_proc1 exch cvlit def + _proc1 aload pop + _proc2 aload pop + _proc1 length + _proc2 length add + packedarray cvx + }{ + /_proc2 exch cvlit def + /_proc1 exch cvlit def + /_newproc _proc1 length _proc2 length add array def + _newproc 0 _proc1 putinterval + _newproc _proc1 length _proc2 putinterval + _newproc cvx + } ifelse +} def +/ci6istint { + type /arraytype eq +} def +/ci6isspot { + dup type /arraytype eq { + dup length 1 sub get /Separation eq + }{ + pop false + } ifelse +} def +/ci6spotname { + dup ci6isspot {dup length 2 sub get}{pop ()} ifelse +} def +/ci6altspace { + aload pop pop pop ci6colormake +} def +/ci6numcomps { + dup /DeviceGray eq { + pop 1 + }{ + dup /DeviceRGB eq { + pop 3 + }{ + /DeviceCMYK eq { + 4 + }{ + 1 + } ifelse + } ifelse + } ifelse +} def +/ci6marksplate { + dup /DeviceGray eq { + pop plateindex 3 eq + }{ + dup /DeviceRGB eq { + pop plateindex 5 ne + }{ + dup /DeviceCMYK eq { + pop plateindex 5 ne + }{ + dup ci6isspot { + /findcmykcustomcolor where { + pop + dup length 2 sub get + 0.1 0.1 0.1 0.1 5 -1 roll + findcmykcustomcolor 1 setcustomcolor + systemdict /currentgray get exec + 1 ne + }{ + pop plateindex 5 ne + } ifelse + }{ + pop plateindex 5 ne + } ifelse + } ifelse + } ifelse + } ifelse +} def +/ci6colormake { + dup ci6numcomps + exch 1 index 2 add 1 roll + dup 1 eq {pop}{array astore} ifelse + exch +} def +/ci6colorexpand { + dup ci6spotname exch + dup ci6istint { + ci6altspace + exch 4 1 roll + }{ + 1 3 1 roll + } ifelse +} def +/ci6colortint { + dup /DeviceGray eq { + 3 1 roll 1 exch sub mul 1 exch sub exch + }{ + dup /DeviceRGB eq { + 3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch + }{ + dup /DeviceCMYK eq { + 3 1 roll {1 index mul exch} forall pop 4 array astore exch + }{ + 3 1 roll mul exch + } ifelse + } ifelse + } ifelse +} def +/ci6colortocmyk { + dup /DeviceGray eq { + pop 1 exch sub 0 0 0 4 -1 roll 4 array astore + }{ + dup /DeviceRGB eq { + pop aload pop _rgbtocmyk 4 array astore + }{ + dup /DeviceCMYK eq { + pop + }{ + ci6altspace ci6colortint ci6colortocmyk + } ifelse + } ifelse + } ifelse +} def +/ci6makeimagedict { + 7 dict begin + /ImageType 1 def + /Decode exch def + /DataSource exch def + /ImageMatrix exch def + /BitsPerComponent exch def + /Height exch def + /Width exch def + currentdict end +} def +/ci6stringinvert { + 0 1 2 index length 1 sub { + dup 2 index exch get 255 exch sub 2 index 3 1 roll put + } for +} def +/ci6stringknockout { + 0 1 2 index length 1 sub { + 255 2 index 3 1 roll put + } for +} def +/ci6stringapply { + 0 1 4 index length 1 sub { + dup + 4 index exch get + 3 index 3 1 roll + 3 index exec + } for + pop exch pop +} def +/ci6walkrgbstring { + 0 3 index + dup length 1 sub 0 3 3 -1 roll { + 3 getinterval {} forall + 5 index exec + 3 index + } for + + 5 {pop} repeat +} def +/ci6walkcmykstring +{ + 0 3 index + dup length 1 sub 0 4 3 -1 roll { + 4 getinterval {} forall + + 6 index exec + + 3 index + + } for + + 5 { pop } repeat + +} def +/ci6putrgbtograystr +{ + .11 mul exch + + .59 mul add exch + + .3 mul add + + cvi 3 copy put + + pop 1 add +} def +/ci6putcmyktograystr +{ + exch .11 mul add + + exch .59 mul add + + exch .3 mul add + + dup 255 gt { pop 255 } if + + 255 exch sub cvi 3 copy put + + pop 1 add +} def +/ci6rgbtograyproc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + XIBuffer3 + dup 3 1 roll + + /ci6putrgbtograystr load exch + ci6walkrgbstring + end +} def +/ci6cmyktograyproc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + XIBuffer3 + dup 3 1 roll + + /ci6putcmyktograystr load exch + ci6walkcmykstring + end +} def +/ci6separatecmykproc { + Adobe_ColorImage_AI6_Vars begin + sourcearray 0 get exec + + XIBuffer3 + + 0 2 index + + plateindex 4 2 index length 1 sub { + get 255 exch sub + + 3 copy put pop 1 add + + 2 index + } for + pop pop exch pop + end +} def + +/ci6compositeimage { + dup 1 eq { + pop pop image + }{ + /ci6colorimage load null ne { + ci6colorimage + }{ + 3 1 roll pop + sourcearray 0 3 -1 roll put + 3 eq {/ci6rgbtograyproc}{/ci6cmyktograyproc} ifelse load + image + } ifelse + } ifelse +} def +/ci6knockoutimage { + gsave + 0 ci6curtransfer exec 1 ci6curtransfer exec + eq { + 0 ci6curtransfer exec 0.5 lt + }{ + 0 ci6curtransfer exec 1 ci6curtransfer exec gt + } ifelse + {{pop 0}}{{pop 1}} ifelse + systemdict /settransfer get exec + ci6compositeimage + grestore +} def +/ci6drawimage { + ci6testplate -1 eq { + pop ci6compositeimage + }{ + dup type /arraytype eq { + dup length plateindex gt {plateindex get}{pop false} ifelse + }{ + { + true + }{ + dup 1 eq {plateindex 3 eq}{plateindex 3 le} ifelse + } ifelse + } ifelse + { + dup 1 eq { + pop pop ci6image + }{ + dup 3 eq { + ci6compositeimage + }{ + pop pop + sourcearray 0 3 -1 roll put + /ci6separatecmykproc load + ci6image + } ifelse + } ifelse + }{ + ci6curoverprint { + 7 {pop} repeat + }{ + ci6knockoutimage + } ifelse + } ifelse + } ifelse +} def +/ci6proctintimage { + /_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store + /_pticomps _ptispace ci6numcomps store + /_ptiscale _pti1 _pti0 sub store + level2? { + _ptiname length 0 gt version cvr 2012 ge and { + [/Separation _ptiname _ptispace {_ptiproc}] setcolorspace + [_pti0 _pti1] ci6makeimagedict ci6image + }{ + [/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace + [0 255] ci6makeimagedict ci6image + } ifelse + }{ + _pticomps 1 eq { + { + dup + { + 255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put + } ci6stringapply + } ci6concatprocs ci6image + }{ + { + dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse + _ptibuf { + exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc + _pticomps 2 add -2 roll + _pticomps 1 sub -1 0 { + 1 index add 2 index exch + 5 -1 roll + 255 mul cvi put + } for + pop pop + } ci6stringapply + } ci6concatprocs false _pticomps + /ci6colorimage load null eq {7 {pop} repeat}{ci6colorimage} ifelse + } ifelse + } ifelse +} def +/ci6graytintimage { + /_gtigray 5 -1 roll store + {1 _gtigray sub mul 1 exch sub} 4 1 roll + /DeviceGray ci6proctintimage +} def +/ci6cmyktintimage { + /_cticmyk 5 -1 roll store + {_cticmyk {1 index mul exch} forall pop} 4 1 roll + /DeviceCMYK ci6proctintimage +} def +/ci6rgbtintimage { + /_rtirgb 5 -1 roll store + {_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll + /DeviceRGB ci6proctintimage +} def +/ci6tintimage { + ci6testplate -1 eq { + ci6colorexpand + 3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll + dup /DeviceGray eq { + pop ci6graytintimage + }{ + dup /DeviceRGB eq { + pop ci6rgbtintimage + }{ + pop ci6cmyktintimage + } ifelse + } ifelse + }{ + dup ci6marksplate { + plateindex 5 lt { + ci6colortocmyk plateindex get + dup 0 eq ci6curoverprint and { + 7 {pop} repeat + }{ + 1 exch sub + exch {1 0}{0 1} ifelse () ci6graytintimage + } ifelse + }{ + pop exch {0}{0 exch} ifelse 0 3 1 roll () ci6graytintimage + } ifelse + }{ + ci6curoverprint { + 8 {pop} repeat + }{ + pop pop pop + {pop 1} 0 1 () /DeviceGray ci6proctintimage + } ifelse + } ifelse + } ifelse +} def +/XINullImage { +} def +/XIImageMask { + XIImageWidth XIImageHeight false + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + imagemask +} def +/XIImageTint { + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + XIType 3 eq XIColorValues XIColorSpace ci6tintimage +} def +/XIImage { + XIImageWidth XIImageHeight XIBitsPerPixel + [XIImageWidth 0 0 XIImageHeight neg 0 0] + /XIDataProc load + false XIChannelCount XIPlateList ci6drawimage +} def +/XG { + pop pop +} def +/XF { + 13 {pop} repeat +} def +/Xh { + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + /XIImageHeight exch def + /XIImageWidth exch def + /XIImageMatrix exch def + 0 0 moveto + XIImageMatrix concat + XIImageWidth XIImageHeight scale + + /_lp /null ddef + _fc + /_lp /imagemask ddef + end +} def +/XH { + Adobe_ColorImage_AI6_Vars begin + grestore + end +} def +/XIEnable { + Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put +} def +/XC { + Adobe_ColorImage_AI6_Vars begin + ci6colormake + /XIColorSpace exch def + /XIColorValues exch def + end +} def +/XIPlates { + Adobe_ColorImage_AI6_Vars begin + /XIPlateList exch def + end +} def +/XI +{ + Adobe_ColorImage_AI6_Vars begin + gsave + /XIType exch def + cvi dup + 256 idiv /XICompression exch store + 256 mod /XIEncoding exch store + pop pop + /XIChannelCount exch def + /XIBitsPerPixel exch def + /XIImageHeight exch def + /XIImageWidth exch def + pop pop pop pop + /XIImageMatrix exch def + XIBitsPerPixel 1 eq { + XIImageWidth 8 div ceiling cvi + }{ + XIImageWidth XIChannelCount mul + } ifelse + /XIRowBytes exch def + XIEnable { + /XIBuffer3 XIImageWidth string def + XICompression 0 eq { + /XIBuffer1 XIRowBytes string def + XIEncoding 0 eq { + {currentfile XIBuffer1 readhexstring pop} + }{ + {currentfile XIBuffer1 readstring pop} + } ifelse + }{ + /XIBuffer1 256 string def + /XIBuffer2 XIRowBytes string def + {currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if} + /ASCII85Decode filter /DCTDecode filter + /XIFile exch def + {XIFile XIBuffer2 readstring pop} + } ifelse + /XIDataProc exch def + + XIType 1 ne { + 0 setgray + } if + XIType 1 eq { + XIImageMask + }{ + XIType 2 eq XIType 3 eq or { + XIImageTint + }{ + XIImage + } ifelse + } ifelse + }{ + XINullImage + } ifelse + /XIPlateList false def + grestore + end +} def +end +%%EndProcSet +%%BeginResource: procset Adobe_Illustrator_AI5 1.3 0 +%%Title: (Adobe Illustrator (R) Version 8.0 Full Prolog) +%%Version: 1.3 0 +%%CreationDate: (3/7/1994) () +%%Copyright: ((C) 1987-1998 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_Illustrator_AI5_vars 112 dict dup begin +put +/_?cmyk false def +/_eo false def +/_lp /none def +/_pf +{ +} def +/_ps +{ +} def +/_psf +{ +} def +/_pss +{ +} def +/_pjsf +{ +} def +/_pjss +{ +} def +/_pola 0 def +/_doClip 0 def +/cf currentflat def +/_lineorientation 0 def +/_charorientation 0 def +/_yokoorientation 0 def +/_tm matrix def +/_renderStart +[ +/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0 +] def +/_renderEnd +[ +null null null null /i1 /i1 /i1 /i1 +] def +/_render -1 def +/_shift [0 0] def +/_ax 0 def +/_ay 0 def +/_cx 0 def +/_cy 0 def +/_leading +[ +0 0 +] def +/_ctm matrix def +/_mtx matrix def +/_sp 16#020 def +/_hyphen (-) def +/_fontSize 0 def +/_fontAscent 0 def +/_fontDescent 0 def +/_fontHeight 0 def +/_fontRotateAdjust 0 def +/Ss 256 string def +Ss 0 (fonts/) putinterval +/_cnt 0 def +/_scale [1 1] def +/_nativeEncoding 0 def +/_useNativeEncoding 0 def +/_tempEncode 0 def +/_pntr 0 def +/_tDict 2 dict def +/_hfname 100 string def +/_hffound false def +/Tx +{ +} def +/Tj +{ +} def +/CRender +{ +} def +/_AI3_savepage +{ +} def +/_gf null def +/_cf 4 array def +/_rgbf 3 array def +/_if null def +/_of false def +/_fc +{ +} def +/_gs null def +/_cs 4 array def +/_rgbs 3 array def +/_is null def +/_os false def +/_sc +{ +} def +/_pd 1 dict def +/_ed 15 dict def +/_pm matrix def +/_fm null def +/_fd null def +/_fdd null def +/_sm null def +/_sd null def +/_sdd null def +/_i null def +/_lobyte 0 def +/_hibyte 0 def +/_cproc null def +/_cscript 0 def +/_hvax 0 def +/_hvay 0 def +/_hvwb 0 def +/_hvcx 0 def +/_hvcy 0 def +/_bitfont null def +/_bitlobyte 0 def +/_bithibyte 0 def +/_bitkey null def +/_bitdata null def +/_bitindex 0 def +/discardSave null def +/buffer 256 string def +/beginString null def +/endString null def +/endStringLength null def +/layerCnt 1 def +/layerCount 1 def +/perCent (%) 0 get def +/perCentSeen? false def +/newBuff null def +/newBuffButFirst null def +/newBuffLast null def +/clipForward? false def +end +userdict /Adobe_Illustrator_AI5 known not { + userdict /Adobe_Illustrator_AI5 100 dict put +} if +userdict /Adobe_Illustrator_AI5 get begin +/initialize +{ + Adobe_Illustrator_AI5 dup begin + Adobe_Illustrator_AI5_vars begin + /_aicmykps where {pop /_?cmyk _aicmykps def}if + discardDict + { + bind pop pop + } forall + dup /nc get begin + { + dup xcheck 1 index type /operatortype ne and + { + bind + } if + pop pop + } forall + end + newpath +} def +/terminate +{ + end + end +} def +/_ +null def +/ddef +{ + Adobe_Illustrator_AI5_vars 3 1 roll put +} def +/xput +{ + dup load dup length exch maxlength eq + { + dup dup load dup + length 2 mul dict copy def + } if + load begin + def + end +} def +/npop +{ + { + pop + } repeat +} def +/hswj +{ + dup stringwidth 3 2 roll + { + _hvwb eq { exch _hvcx add exch _hvcy add } if + exch _hvax add exch _hvay add + } cforall +} def +/vswj +{ + 0 0 3 -1 roll + { + dup 255 le + _charorientation 1 eq + and + { + dup cstring stringwidth 5 2 roll + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + 4 -1 roll sub exch + 3 -1 roll sub exch + } + { + _hvwb eq { exch _hvcy sub exch _hvcx sub } if + exch _hvay sub exch _hvax sub + _fontHeight sub + } ifelse + } cforall +} def +/swj +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hswj } { vswj } ifelse +} def +/sw +{ + 0 0 0 6 3 roll swj +} def +/vjss +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + gsave + 2 index false charpath + 6 index setmatrix stroke + grestore + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjss +{ + 4 1 roll + { + dup cstring + gsave + false charpath currentpoint + 5 index setmatrix stroke + grestore + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jss +{ + _lineorientation 0 eq { hjss } { vjss } ifelse +} def +/ss +{ + 0 0 0 7 3 roll jss +} def +/vjsp +{ + 4 1 roll + { + dup cstring + dup length 1 eq + _charorientation 1 eq + and + { + -90 rotate + currentpoint + _fontRotateAdjust add + moveto + false charpath + currentpoint + _fontRotateAdjust sub + moveto + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + 5 index sub + 3 index _sp eq + { + 9 index sub + } if + + currentpoint + exch 4 index stringwidth pop 2 div sub + exch _fontAscent sub + moveto + + 2 index false charpath + + moveto pop pop + } ifelse + } cforall + 6 npop +} def +/hjsp +{ + 4 1 roll + { + dup cstring + false charpath + _sp eq + { + 5 index 5 index rmoveto + } if + 2 copy rmoveto + } cforall + 6 npop +} def +/jsp +{ + matrix currentmatrix + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/sp +{ + matrix currentmatrix + 0 0 0 7 3 roll + _lineorientation 0 eq {hjsp} {vjsp} ifelse +} def +/pl +{ + transform + 0.25 sub round 0.25 add exch + 0.25 sub round 0.25 add exch + itransform +} def +/setstrokeadjust where +{ + pop true setstrokeadjust + /c + { + curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll curveto + } def + /V + /v load def + /y + { + 2 copy curveto + } def + /Y + /y load def + /l + { + lineto + } def + /L + /l load def + /m + { + moveto + } def +} +{ + /c + { + pl curveto + } def + /C + /c load def + /v + { + currentpoint 6 2 roll pl curveto + } def + /V + /v load def + /y + { + pl 2 copy curveto + } def + /Y + /y load def + /l + { + pl lineto + } def + /L + /l load def + /m + { + pl moveto + } def +} ifelse +/d +{ + setdash +} def +/cf +{ +} def +/i +{ + dup 0 eq + { + pop cf + } if + setflat +} def +/j +{ + setlinejoin +} def +/J +{ + setlinecap +} def +/M +{ + setmiterlimit +} def +/w +{ + setlinewidth +} def +/XR +{ + 0 ne + /_eo exch ddef +} def +/H +{ +} def +/h +{ + closepath +} def +/N +{ + _pola 0 eq + { + _doClip 1 eq + { + _eo {eoclip} {clip} ifelse /_doClip 0 ddef + } if + newpath + } + { + /CRender + { + N + } ddef + } ifelse +} def +/n +{ + N +} def +/F +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc + /_doClip 0 ddef + } + { + _pf + } ifelse + } + { + /CRender + { + F + } ddef + } ifelse +} def +/f +{ + closepath + F +} def +/S +{ + _pola 0 eq + { + _doClip 1 eq + { + gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + _ps + } ifelse + } + { + /CRender + { + S + } ddef + } ifelse +} def +/s +{ + closepath + S +} def +/B +{ + _pola 0 eq + { + _doClip 1 eq + gsave F grestore + { + gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc + /_doClip 0 ddef + } + { + S + } ifelse + } + { + /CRender + { + B + } ddef + } ifelse +} def +/b +{ + closepath + B +} def +/W +{ + /_doClip 1 ddef +} def +/* +{ + count 0 ne + { + dup type /stringtype eq + { + pop + } if + } if + newpath +} def +/u +{ +} def +/U +{ +} def +/q +{ + _pola 0 eq + { + gsave + } if +} def +/Q +{ + _pola 0 eq + { + grestore + } if +} def +/*u +{ + _pola 1 add /_pola exch ddef +} def +/*U +{ + _pola 1 sub /_pola exch ddef + _pola 0 eq + { + CRender + } if +} def +/D +{ + pop +} def +/*w +{ +} def +/*W +{ +} def +/` +{ + /_i save ddef + clipForward? + { + nulldevice + } if + 6 1 roll 4 npop + concat pop + userdict begin + /showpage + { + } def + 0 setgray + 0 setlinecap + 1 setlinewidth + 0 setlinejoin + 10 setmiterlimit + [] 0 setdash + /setstrokeadjust where {pop false setstrokeadjust} if + newpath + 0 setgray + false setoverprint +} def +/~ +{ + end + _i restore +} def +/_rgbtocmyk +{ + 3 + { + 1 exch sub 3 1 roll + } repeat + 3 copy 1 4 1 roll + 3 + { + 3 index 2 copy gt + { + exch + } if + pop 4 1 roll + } repeat + pop pop pop + 4 1 roll + 3 + { + 3 index sub + 3 1 roll + } repeat + 4 -1 roll +} def +/setrgbfill +{ + _rgbf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _rgbf aload pop setrgbcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/setrgbstroke +{ + _rgbs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _rgbs aload pop setrgbcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/O +{ + 0 ne + /_of exch ddef + /_lp /none ddef +} def +/R +{ + 0 ne + /_os exch ddef + /_lp /none ddef +} def +/g +{ + /_gf exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _gf setgray + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/G +{ + /_gs exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _gs setgray + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/k +{ + _cf astore pop + /_fc + { + _lp /fill ne + { + _of setoverprint + _cf aload pop setcmykcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/K +{ + _cs astore pop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _cs aload pop setcmykcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/Xa +{ + _?cmyk { + 3 npop k + }{ + setrgbfill 4 npop + } ifelse +} def +/XA +{ + _?cmyk { + 3 npop K + }{ + setrgbstroke 4 npop + } ifelse +} def +/Xs +{ + /_gf exch ddef + 5 npop + /_fc + { + _lp /fill ne + { + _of setoverprint + _gf setAIseparationgray + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XS +{ + /_gs exch ddef + 5 npop + /_sc + { + _lp /stroke ne + { + _os setoverprint + _gs setAIseparationgray + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/Xx +{ + exch + /_gf exch ddef + 0 eq { + findcmykcustomcolor + }{ + _?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse + { + 4 1 roll 3 npop + findcmykcustomcolor + }{ + 8 -4 roll 4 npop + findrgbcustomcolor + } ifelse + } ifelse + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/XX +{ + exch + /_gs exch ddef + 0 eq { + findcmykcustomcolor + }{ + _?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse + { + 4 1 roll 3 npop + findcmykcustomcolor + }{ + 8 -4 roll 4 npop + findrgbcustomcolor + } ifelse + } ifelse + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/x +{ + /_gf exch ddef + findcmykcustomcolor + /_if exch ddef + /_fc + { + _lp /fill ne + { + _of setoverprint + _if _gf 1 exch sub setcustomcolor + /_lp /fill ddef + } if + } ddef + /_pf + { + _fc + _eo {eofill} {fill} ifelse + } ddef + /_psf + { + _fc + hvashow + } ddef + /_pjsf + { + _fc + hvawidthshow + } ddef + /_lp /none ddef +} def +/X +{ + /_gs exch ddef + findcmykcustomcolor + /_is exch ddef + /_sc + { + _lp /stroke ne + { + _os setoverprint + _is _gs 1 exch sub setcustomcolor + /_lp /stroke ddef + } if + } ddef + /_ps + { + _sc + stroke + } ddef + /_pss + { + _sc + ss + } ddef + /_pjss + { + _sc + jss + } ddef + /_lp /none ddef +} def +/XK +{ + 3 -1 roll pop + 0 eq + { + 1 exch sub + 3 {dup 3 1 roll mul 5 1 roll} repeat + mul 4 1 roll + K + } + { + 1 exch sub 4 1 roll + 3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat + 4 -1 roll pop + XA + } ifelse +} def +/Xk +{ + 3 -1 roll pop + 0 eq + { + 1 exch sub + 3 {dup 3 1 roll mul 5 1 roll} repeat + mul 4 1 roll + k + } + { + 1 exch sub 4 1 roll + 3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat + 4 -1 roll pop + Xa + } ifelse +} def +/A +{ + pop +} def +/annotatepage +{ +userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse +} def +/XT { + pop pop +} def +/Xt { + pop +} def +/discard +{ + save /discardSave exch store + discardDict begin + /endString exch store + gt38? + { + 2 add + } if + load + stopped + pop + end + discardSave restore +} bind def +userdict /discardDict 7 dict dup begin +put +/pre38Initialize +{ + /endStringLength endString length store + /newBuff buffer 0 endStringLength getinterval store + /newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store + /newBuffLast newBuff endStringLength 1 sub 1 getinterval store +} def +/shiftBuffer +{ + newBuff 0 newBuffButFirst putinterval + newBuffLast 0 + currentfile read not + { + stop + } if + put +} def +0 +{ + pre38Initialize + mark + currentfile newBuff readstring exch pop + { + { + newBuff endString eq + { + cleartomark stop + } if + shiftBuffer + } loop + } + { + stop + } ifelse +} def +1 +{ + pre38Initialize + /beginString exch store + mark + currentfile newBuff readstring exch pop + { + { + newBuff beginString eq + { + /layerCount dup load 1 add store + } + { + newBuff endString eq + { + /layerCount dup load 1 sub store + layerCount 0 eq + { + cleartomark stop + } if + } if + } ifelse + shiftBuffer + } loop + } if +} def +2 +{ + mark + { + currentfile buffer {readline} stopped { + % assume error was due to overfilling the buffer + }{ + not + { + stop + } if + endString eq { + cleartomark stop + } if + }ifelse + } loop +} def +3 +{ + /beginString exch store + /layerCnt 1 store + mark + { + currentfile buffer {readline} stopped { + % assume error was due to overfilling the buffer + }{ + not + { + stop + } if + dup beginString eq + { + pop /layerCnt dup load 1 add store + } + { + endString eq + { + layerCnt 1 eq + { + cleartomark stop + } + { + /layerCnt dup load 1 sub store + } ifelse + } if + } ifelse + }ifelse + } loop +} def +end +userdict /clipRenderOff 15 dict dup begin +put +{ + /n /N /s /S /f /F /b /B +} +{ + { + _doClip 1 eq + { + /_doClip 0 ddef _eo {eoclip} {clip} ifelse + } if + newpath + } def +} forall +/Tr /pop load def +/Bb {} def +/BB /pop load def +/Bg {12 npop} def +/Bm {6 npop} def +/Bc /Bm load def +/Bh {4 npop} def +end +/Lb +{ + 6 npop + 7 2 roll + 5 npop + 0 eq + { + 0 eq + { + (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard + } + { + + /clipForward? true def + + /Tx /pop load def + /Tj /pop load def + + currentdict end clipRenderOff begin begin + } ifelse + } + { + 0 eq + { + save /discardSave exch store + } if + } ifelse +} bind def +/LB +{ + discardSave dup null ne + { + restore + } + { + pop + clipForward? + { + currentdict + end + end + begin + + /clipForward? false ddef + } if + } ifelse +} bind def +/Pb +{ + pop pop + 0 (%AI5_EndPalette) discard +} bind def +/Np +{ + 0 (%AI5_End_NonPrinting--) discard +} bind def +/Ln /pop load def +/Ap +/pop load def +/Ar +{ + 72 exch div + 0 dtransform dup mul exch dup mul add sqrt + dup 1 lt + { + pop 1 + } if + setflat +} def +/Mb +{ + q +} def +/Md +{ +} def +/MB +{ + Q +} def +/nc 4 dict def +nc begin +/setgray +{ + pop +} bind def +/setcmykcolor +{ + 4 npop +} bind def +/setrgbcolor +{ + 3 npop +} bind def +/setcustomcolor +{ + 2 npop +} bind def +currentdict readonly pop +end +/XP +{ + 4 npop +} bind def +/XD +{ + pop +} bind def +end +setpacking +%%EndResource +%%BeginResource: procset Adobe_cshow 2.0 8 +%%Title: (Writing System Operators) +%%Version: 2.0 8 +%%CreationDate: (1/23/89) () +%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved) +currentpacking true setpacking +userdict /Adobe_cshow 14 dict dup begin put +/initialize +{ + Adobe_cshow begin + Adobe_cshow + { + dup xcheck + { + bind + } if + pop pop + } forall + end + Adobe_cshow begin +} def +/terminate +{ +currentdict Adobe_cshow eq + { + end + } if +} def +/cforall +{ + /_lobyte 0 ddef + /_hibyte 0 ddef + /_cproc exch ddef + /_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef + { + /_lobyte exch ddef + _hibyte 0 eq + _cscript 1 eq + _lobyte 129 ge _lobyte 159 le and + _lobyte 224 ge _lobyte 252 le and or and + _cscript 2 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 3 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript 25 eq + _lobyte 161 ge _lobyte 254 le and and + _cscript -1 eq + or or or or and + { + /_hibyte _lobyte ddef + } + { + _hibyte 256 mul _lobyte add + _cproc + /_hibyte 0 ddef + } ifelse + } forall +} def +/cstring +{ + dup 256 lt + { + (s) dup 0 4 3 roll put + } + { + dup 256 idiv exch 256 mod + (hl) dup dup 0 6 5 roll put 1 4 3 roll put + } ifelse +} def +/clength +{ + 0 exch + { 256 lt { 1 } { 2 } ifelse add } cforall +} def +/hawidthshow +{ + { + dup cstring + show + _hvax _hvay rmoveto + _hvwb eq { _hvcx _hvcy rmoveto } if + } cforall +} def +/vawidthshow +{ + { + dup 255 le + _charorientation 1 eq + and + { + -90 rotate + 0 _fontRotateAdjust rmoveto + cstring + _hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow + 0 _fontRotateAdjust neg rmoveto + 90 rotate + } + { + currentpoint + _fontHeight sub + exch _hvay sub exch _hvax sub + 2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if + 3 2 roll + cstring + dup stringwidth pop 2 div neg _fontAscent neg rmoveto + show + moveto + } ifelse + } cforall +} def +/hvawidthshow +{ + 6 1 roll + /_hvay exch ddef + /_hvax exch ddef + /_hvwb exch ddef + /_hvcy exch ddef + /_hvcx exch ddef + _lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse +} def +/hvwidthshow +{ + 0 0 3 -1 roll hvawidthshow +} def +/hvashow +{ + 0 0 0 6 -3 roll hvawidthshow +} def +/hvshow +{ + 0 0 0 0 0 6 -1 roll hvawidthshow +} def +currentdict readonly pop end +setpacking +%%EndResource +%%BeginResource: procset Adobe_shading_AI8 1.0 0 +%%Title: (Adobe Illustrator 8 Shading Procset) +%%Version: 1.0 0 +%%CreationDate: (12/17/97) () +%%Copyright: ((C) 1987-1997 Adobe Systems Incorporated All Rights Reserved) +userdict /defaultpacking currentpacking put true setpacking +userdict /Adobe_shading_AI8 10 dict dup begin put +/initialize { + Adobe_shading_AI8 begin + Adobe_shading_AI8 bdprocs + Mesh /initialize get exec +} def +/terminate { + currentdict Adobe_shading_AI8 eq { + end + } if +} def +/bdprocs { + { + dup xcheck 1 index type /arraytype eq and { + bind + } if + pop pop + } forall +} def +/X! {pop} def +/X# {pop pop} def +/Mesh 40 dict def +Mesh begin +/initialize { + Mesh bdprocs + Mesh begin + /emulate? /AI8MeshEmulation where { + pop AI8MeshEmulation + }{ + systemdict /shfill known not + } ifelse def + end +} def +/bd { + shadingdict begin +} def +/paint { + emulate? { + end + }{ + /_lp /none ddef _fc /_lp /none ddef + + /AIColorSpace AIColorSpace tocolorspace store + /ColorSpace AIColorSpace topsspace store + + version_ge_3010.106 not systemdict /setsmoothness known and { + 0.0001 setsmoothness + } if + + composite? { + /DataSource getdatasrc def + Matrix concat + currentdict end + shfill + }{ + AIColorSpace makesmarks AIPlateList markingplate and not isoverprint and { + end + }{ + /ColorSpace /DeviceGray store + /Decode [0 1 0 1 0 1] store + /DataSource getplatesrc def + Matrix concat + currentdict end + shfill + } ifelse + } ifelse + } ifelse +} def +/shadingdict 12 dict def +shadingdict begin + /ShadingType 6 def + /BitsPerCoordinate 16 def + /BitsPerComponent 8 def + /BitsPerFlag 8 def +end +/datafile null def +/databuf 256 string def +/dataptr 0 def +/srcspace null def +/srcchannels 0 def +/dstchannels 0 def +/dstplate 0 def +/srctodstcolor null def +/getplatesrc { + /srcspace AIColorSpace store + /srcchannels AIColorSpace getnchannels store + /dstchannels 1 store + /dstplate getplateindex store + /srctodstcolor srcspace makesmarks { + dstplate 4 eq { + {1 exch sub} + }{ + {srcspace tocmyk 3 dstplate sub index 1 exch sub 5 1 roll 4 {pop} repeat} + } ifelse + }{ + {srcchannels {pop} repeat 1} + } ifelse store + /datafile getdatasrc store + /rdpatch168 load DataLength () /SubFileDecode filter +} def +/getdatasrc { + /rdcmntline load /ASCII85Decode filter +} def +/rdpatch168 { + /dataptr 0 store + 49 rdcount + 4 { + dup {pop srcchannels getint8} if + dup {pop srctodstcolor dstchannels putint8 true} if + } repeat + {databuf 0 dataptr getinterval}{()} ifelse +} def +/rdpatch3216 { + /dataptr 0 store + 97 rdcount + 4 { + dup {pop srcchannels getint16} if + dup {pop srctodstcolor dstchannels putint16 true} if + } repeat + {databuf 0 dataptr getinterval}{()} ifelse +} def +/rdcount { + dup 0 gt { + datafile databuf dataptr 4 -1 roll getinterval readstring + exch length dataptr add /dataptr exch store + }{ + true + } ifelse +} def +/getint8 { + mark true 3 -1 roll + { + dup {pop datafile read} if + dup {pop 255 div true} if + } repeat + { + counttomark 1 add -1 roll pop true + }{ + cleartomark false + } ifelse +} def +/putint8 { + dup dataptr add /dataptr exch store + dataptr exch + { + 1 sub exch + 255 mul cvi + databuf 2 index + 3 -1 roll put + } repeat + pop +} def +/getint16 { + mark true 3 -1 roll + { + dup {pop datafile read} if + dup {pop 256 mul datafile read} if + dup {pop add 65535 div true} if + } repeat + { + counttomark 1 add -1 roll pop true + }{ + cleartomark false + } ifelse +} def +/putint16 { + dup 2 mul dataptr add /dataptr exch store + dataptr exch + { + 2 sub exch + 65535 mul cvi dup + 256 idiv databuf 3 index 3 -1 roll put + 256 mod databuf 2 index 1 add 3 -1 roll put + } repeat + pop +} def +/srcbuf 256 string def +/rdcmntline { + currentfile srcbuf readline pop + (%) anchorsearch {pop} if +} def +/getplateindex { + 0 [cyan? magenta? yellow? black? customColor?] {{exit} if 1 add} forall +} def +/aicsarray 4 array def +/aicsaltvals 4 array def +/aicsaltcolr aicsaltvals def +/tocolorspace { + dup type /arraytype eq { + mark exch aload pop + aicsarray 0 3 -1 roll put + aicsarray 1 3 -1 roll put + dup aicsarray 2 3 -1 roll put + gettintxform aicsarray 3 3 -1 roll put + counttomark aicsaltvals 0 3 -1 roll getinterval /aicsaltcolr exch store + aicsaltcolr astore pop pop + aicsarray + } if +} def +/subtintxform {aicsaltcolr {1 index mul exch} forall pop} def +/addtintxform {aicsaltcolr {1 sub 1 index mul 1 add exch} forall pop} def +/gettintxform { + /DeviceRGB eq {/addtintxform}{/subtintxform} ifelse load +} def +/getnchannels { + dup type /arraytype eq {0 get} if + colorspacedict exch get begin Channels end +} def +/makesmarks { + composite? { + pop true + }{ + dup dup type /arraytype eq {0 get} if + colorspacedict exch get begin MarksPlate end + } ifelse +} def +/markingplate { + composite? { + pop true + }{ + dup type /arraytype eq { + dup length getplateindex gt {getplateindex get}{pop false} ifelse + } if + } ifelse +} def +/tocmyk { + dup dup type /arraytype eq {0 get} if + colorspacedict exch get begin ToCMYK end +} def +/topsspace { + dup dup type /arraytype eq {0 get} if + colorspacedict exch get begin ToPSSpace end +} def +/colorspacedict 5 dict dup begin + /DeviceGray 4 dict dup begin + /Channels 1 def + /MarksPlate {pop black?} def + /ToCMYK {pop 1 exch sub 0 0 0 4 -1 roll} def + /ToPSSpace {} def + end def + /DeviceRGB 4 dict dup begin + /Channels 3 def + /MarksPlate {pop isCMYKSep?} def + /ToCMYK {pop _rgbtocmyk} def + /ToPSSpace {} def + end def + /DeviceCMYK 4 dict dup begin + /Channels 4 def + /MarksPlate {pop isCMYKSep?} def + /ToCMYK {pop} def + /ToPSSpace {} def + end def + /Separation 4 dict dup begin + /Channels 1 def + /MarksPlate { + /findcmykcustomcolor where { + pop dup 1 exch ToCMYK 5 -1 roll 1 get + findcmykcustomcolor 1 setcustomcolor + systemdict /currentgray get exec + 1 ne + }{ + pop false + } ifelse + } def + /ToCMYK { + dup 2 get mark exch 4 2 roll + 3 get exec + counttomark -1 roll tocmyk + 5 -1 roll pop + } def + /ToPSSpace {} def + end def + /Process 4 dict dup begin + /Channels 1 def + /MarksPlate { + isCMYKSep? { + 1 exch ToCMYK 4 array astore getplateindex get 0 ne + }{ + pop false + } ifelse + } def + /ToCMYK { + dup 2 get mark exch 4 2 roll + 3 get exec + counttomark -1 roll tocmyk + 5 -1 roll pop + } def + /ToPSSpace { + 4 array copy dup 0 /Separation put + } def + end def +end def +/isoverprint { + /currentoverprint where {pop currentoverprint}{_of} ifelse +} def +/version_ge_3010.106 { + version {cvr} stopped { + pop + false + }{ + 3010.106 ge + } ifelse +} def +end +end +defaultpacking setpacking +%%EndResource +%%EndProlog %%BeginSetup userdict /_useSmoothShade false put userdict /_aicmykps true put userdict /_forceToCMYK true put Adobe_level2_AI5 /initialize get exec +Adobe_cshow /initialize get exec +Adobe_ColorImage_AI6 /initialize get exec +Adobe_shading_AI8 /initialize get exec +Adobe_Illustrator_AI5 /initialize get exec +%AI3_BeginRider currentpacking true setpacking setpacking %AI3_EndRider %AI5_Begin_NonPrinting Np %AI8_PluginGroupInfo (Adobe Path Blends) (Adobe Blends Plugin) (LiveBlends.aip) %AI8_PluginGroupInfo (Adobe Tracing Object) (Tracing) (TracingSuite.aip) %AI8_PluginGroupInfo (Adobe Scatter Brush Tool) (Adobe Scatter Brush Plugin) (ScatterBrushTool.aip) %AI8_PluginGroupInfo (Adobe Scatter Brush Tool) (Adobe Scatter Brush Plugin) (ScatterBrushTool.aip) %AI8_PluginGroupInfo (Adobe PatternOnPath Brush Tool) (Adobe Pattern Brush Plugin) (ArtBrushTool.aip) %AI8_PluginGroupInfo (Adobe PatternOnPath Brush Tool) (Adobe Pattern Brush Plugin) (ArtBrushTool.aip) %AI8_PluginGroupInfo (Adobe ArtOnPath Brush Tool) (Adobe Art Brush Plugin) (ArtBrushTool.aip) %AI8_PluginGroupInfo (Adobe ArtOnPath Brush Tool) (Adobe Art Brush Plugin) (ArtBrushTool.aip) %AI8_PluginGroupInfo (Adobe Calligraphic Brush Tool) (Adobe Calligraphic Brush Plugin) (CalligBrushTool.aip) %AI8_PluginGroupInfo (Adobe Flare Plugin) (Flare) (Flare.aip) %AI8_PluginGroupInfo (Adobe Symbolism) (Adobe Symbolism) (ParticleSystem.aip) %AI8_PluginGroupInfo (Adobe Deform Plugin) (Adobe Envelope Plugin) (Envelope and Warp.aip) %AI8_PluginGroupInfo (Pathfinder Suite) (Adobe Compound Shape) (PathFinderS.aip) %AI8_PluginGroupInfo (Adobe Planar Group) (Adobe Live Paint Plugin) (Live Paint.aip) %AI5_End_NonPrinting-- %AI5_BeginPalette 0 0 Pb 0.74902 0.678431 0.670588 0.901961 ([Registration]) 0 Xs ([Registration]) Pc PB %AI5_EndPalette %%EndSetup %AI5_BeginLayer 1 1 1 1 0 0 1 0 79 128 255 0 50 Lb (svg2279) Ln 0 A u U u u u 0 O 0 0 0 0 1 1 1 Xa 0 R 0.74902 0.678431 0.670588 0.901961 0 0 0 XA 0 J 0 j 1.04162 w 4 M []0 d 0 XR 360.9937 306.4668 m 439.9941 306.4668 L 439.9941 292.4668 L 360.9937 292.4668 L 360.9937 306.4668 L b 0.74902 0.678431 0.670588 0.901961 0 0 0 Xa 1 w 362.4751 305.0669 m 438.5127 305.0669 L 438.5127 293.8672 L 362.4751 293.8672 L 362.4751 305.0669 L f 1 D 0.345098 0.239216 0.309804 0 0.670588 0.694118 0.666667 Xa 362.4751 305.0547 m 362.4751 293.8545 L 382.5557 293.8545 L 383.8477 295.4883 384.7197 297.3867 384.7197 299.4546 c 384.7197 301.5088 383.8628 303.4282 382.5864 305.0547 C 362.4751 305.0547 L f q 0 D 362.6411 305.0669 m 382.2085 305.0669 L 382.2085 293.8672 L 362.6411 293.8672 L 362.6411 305.0669 L h W n u 0 O 0 0 0 0 1 1 1 Xa 379.79 299.4668 m 379.792 295.9746 376.7988 293.1426 373.1045 293.1406 c 369.4106 293.1387 366.4136 295.9668 366.4116 299.459 c 366.4116 299.4614 366.4116 299.4639 366.4116 299.4668 c 366.4092 302.9585 369.4023 305.791 373.0967 305.793 C 376.791 305.7949 379.7876 302.9658 379.79 299.4741 c 379.79 299.4717 379.79 299.4692 379.79 299.4668 c f *u 0.74902 0.678431 0.670588 0.901961 0 0 0 Xa 378.5386 304.6162 m 380.0215 303.2144 380.7637 301.4976 380.7637 299.4668 c 380.7637 297.4355 380.0347 295.7373 378.5767 294.3711 C 377.0293 292.9326 375.2012 292.2129 373.0913 292.2129 c 371.0068 292.2129 369.21 292.9268 367.7012 294.3535 C 366.1919 295.7793 365.4375 297.4844 365.4375 299.4668 c 365.4375 301.4492 366.1919 303.166 367.7012 304.6162 C 369.1714 306.019 370.9683 306.7202 373.0913 306.7202 c 375.2397 306.7202 377.0552 306.019 378.5386 304.6162 C f 1 D 368.6997 303.6733 m 367.4453 302.4761 366.8188 301.0737 366.8188 299.4648 c 366.8188 297.8564 367.4395 296.4658 368.6802 295.293 C 369.9214 294.1201 371.3994 293.5332 373.1138 293.5332 c 374.8281 293.5332 376.3184 294.126 377.585 295.3105 C 378.7876 296.4121 379.3892 297.7959 379.3892 299.4648 c 379.3892 301.1211 378.7778 302.5273 377.5562 303.6821 C 376.3345 304.8369 374.8535 305.4146 373.1138 305.4146 c 371.3735 305.4146 369.9019 304.834 368.6997 303.6733 C f 0 D 372 300.1724 m 371.8081 300.5674 371.5215 300.7646 371.1387 300.7646 c 370.4624 300.7646 370.1245 300.3345 370.1245 299.4741 c 370.1245 298.6133 370.4624 298.1836 371.1387 298.1836 c 371.5854 298.1836 371.9043 298.3926 372.0957 298.8125 C 373.0332 298.3408 L 372.5864 297.5898 371.916 297.2148 371.022 297.2148 c 370.3325 297.2148 369.7803 297.415 369.3657 297.8145 C 368.9502 298.2139 368.7432 298.7646 368.7432 299.4668 c 368.7432 300.1567 368.957 300.7041 369.3848 301.1099 C 369.8125 301.5156 370.3452 301.7183 370.9839 301.7183 c 371.9287 301.7183 372.6055 301.3662 373.0146 300.6631 C 372 300.1724 L f 376.4102 300.1724 m 376.2183 300.5674 375.9375 300.7646 375.5669 300.7646 c 374.877 300.7646 374.5317 300.3345 374.5317 299.4741 c 374.5317 298.6133 374.877 298.1836 375.5669 298.1836 c 376.0142 298.1836 376.3271 298.3926 376.5059 298.8125 C 377.4644 298.3408 L 377.0186 297.5898 376.3491 297.2148 375.4565 297.2148 c 374.7681 297.2148 374.2173 297.415 373.8027 297.8145 C 373.3887 298.2139 373.1816 298.7646 373.1816 299.4668 c 373.1816 300.1567 373.3921 300.7041 373.8125 301.1099 C 374.2329 301.5156 374.7681 301.7183 375.4185 301.7183 c 376.3618 301.7183 377.0376 301.3662 377.4448 300.6631 C 376.4102 300.1724 L f *U U /AdobeObjectMatrix (0.961253 0.000000 0.000000 0.961253 6.834157 9.506999) XT Q U /AdobeObjectMatrix (1.000000 0.000000 0.000000 1.000000 158.000000 54.000000) XT 0 A *u 1 D 0 O 0 0 0 0 1 1 1 Xa 0 J 0 j 1 w 4 M []0 d 0 XR 389.5518 300.0986 m 389.7944 300.0986 389.978 300.1484 390.1035 300.2485 c 390.2285 300.3486 390.291 300.4961 390.291 300.6914 c 390.291 300.8838 390.2285 301.0303 390.1035 301.1304 C 389.978 301.2324 389.7944 301.2842 389.5518 301.2842 C 388.7007 301.2842 L 388.7007 300.0986 L 389.5518 300.0986 L F 389.604 297.6494 m 389.9131 297.6494 390.1445 297.7109 390.2993 297.833 C 390.4565 297.9551 390.5352 298.1406 390.5352 298.3887 c 390.5352 298.6309 390.4575 298.8125 390.3032 298.9316 C 390.1489 299.0547 389.9155 299.1162 389.604 299.1162 C 388.7007 299.1162 L 388.7007 297.6494 L 389.604 297.6494 L F 0 D 391.0347 299.6636 m 391.3647 299.5737 391.6206 299.4072 391.8018 299.1646 c 391.9829 298.9219 392.0732 298.625 392.0732 298.2715 c 392.0732 297.7324 391.8789 297.3291 391.4897 297.0645 c 391.1011 296.7988 390.5098 296.666 389.7158 296.666 C 387.1626 296.666 L 387.1626 302.2666 L 389.4722 302.2666 L 390.3008 302.2666 390.8999 302.1494 391.27 301.9141 C 391.6431 301.6792 391.8296 301.3027 391.8296 300.7852 c 391.8296 300.5127 391.7617 300.2798 391.626 300.0874 C 391.4897 299.8975 391.293 299.7559 391.0347 299.6636 C F 391.9395 302.2666 m 393.6216 302.2666 L 394.9805 300.2715 L 396.3389 302.2666 L 398.0249 302.2666 L 395.7515 299.0259 L 395.7515 296.666 L 394.2129 296.666 L 394.2129 299.0259 L 391.9395 302.2666 L F *U U /AdobeObjectMatrix (0.987502 0.000000 0.000000 0.933352 -323.900635 -271.876892) XT U LB %AI5_EndLayer-- %AI3_BeginCrops userdict /AI3_noCropMarks known not { 0 A u u 0 R 0 G 0 J 0 j 0.5 w 4 M []0 d 0 XR 351.5 292 m 324.5 292 L S 360.5 283 m 360.5 256 L S U u 351.5 307 m 324.5 307 L S 360.5 316 m 360.5 343 L S U u 449.5 307 m 476.5 307 L S 440.5 316 m 440.5 343 L S U u 449.5 292 m 476.5 292 L S 440.5 283 m 440.5 256 L S U U } if %AI3_EndCrops %%PageTrailer gsave annotatepage grestore showpage %%Trailer Adobe_Illustrator_AI5 /terminate get exec +Adobe_shading_AI8 /terminate get exec +Adobe_ColorImage_AI6 /terminate get exec +Adobe_cshow /terminate get exec +Adobe_level2_AI5 /terminate get exec +%%EOF \ No newline at end of file diff --git a/doc/paper/CC-by.pdf b/doc/paper/CC-by.pdf new file mode 100755 index 0000000..7b790d0 Binary files /dev/null and b/doc/paper/CC-by.pdf differ diff --git a/doc/paper/iacrtrans.cls b/doc/paper/iacrtrans.cls new file mode 100755 index 0000000..bf42a75 --- /dev/null +++ b/doc/paper/iacrtrans.cls @@ -0,0 +1,448 @@ +% IACR Transactions DOCUMENT CLASS -- version 0.24 (26 August 2016) +% Written by Gaetan Leurent gaetan.leurent@inria.fr (2016) +% +% To the extent possible under law, the author(s) have dedicated all +% copyright and related and neighboring rights to this software to the +% public domain worldwide. This software is distributed without any +% warranty. +% +% You should have received a copy of the CC0 Public Domain Dedication +% along with this software. If not, see +% . +% +% +%%% Class options: +% +% [preprint] Preprint (no copyright info) +% [submission] Anonymous submission +% [spthm] Emulate llncs sptheorem and remove automatic \qed in proof +% [nohyperref] Disable automatic loading of hyperref +% [draft] +% +%%% HOWTO use this class +% +%% Title +% \title[short]{Long title} +% +%% Authors/affiliation: +% \author{Alice \and Bob} +% \institute{ABC\\ \email{alice@abc} \and DEF\\ \email{bob@def}} +% +%% Keywords/abstract: +% \keywords{banana \and apple} +% \begin{abstract} +% Lorem ipsum dolor sit amet... +% \end{abstract} +% +%% Warnings +% - please don't use any \pagestyle of \thispagestyle command +% - if you have proof with explicit \qed inside, you should either +% remove \qed symbols, replace them by \qedhere, or add option [spthm] + +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{iacrtrans}[2016/08/26 v0.24 IACR Transactions Author Class] + +% Common definitions +\def\publname{IACR Transactions on Cryptographic Hardware and Embedded Systems} +\def\IACR@vol{0} +\def\IACR@no{0} +\def\IACR@fp{1} +\def\IACR@DOI{XXXXXXXX} +\usepackage{lastpage} +\def\IACR@lp{\pageref*{LastPage}} + +\newcommand{\setfirstpage}[1]{\def\IACR@fp{#1}\setcounter{page}{#1}} +\newcommand{\setlastpage}[1]{\def\IACR@lp{#1}} +\newcommand{\setvolume}[1]{\def\IACR@vol{#1}} +\newcommand{\setnumber}[1]{\def\IACR@no{#1}} +\newcommand{\setDOI}[1]{\def\IACR@DOI{#1}} + +% Options +\newif\if@loadhr +\@loadhrtrue +\DeclareOption{nohyperref}{\@loadhrfalse} +\newif\if@floatrow +\@floatrowfalse +\DeclareOption{floatrow}{\@floatrowtrue} +\newif\if@submission +\@submissionfalse +\newif\if@preprint +\@preprintfalse +\DeclareOption{final}{\PassOptionsToClass{\CurrentOption}{article}} % Default +\DeclareOption{preprint}{\@preprinttrue} +\DeclareOption{submission}{\@submissiontrue} +\DeclareOption{draft}{\@preprinttrue\PassOptionsToClass{\CurrentOption}{article}} +\newif\if@spthm +\@spthmfalse +\DeclareOption{spthm}{\@spthmtrue} + +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\ProcessOptions\relax + +% article class with a4paper +\LoadClass[10pt,twoside]{article}[2007/10/19] + +% Geometry +\RequirePackage[a4paper,hscale=0.65,vscale=0.75,marginratio=1:1]{geometry} + +% Title fonts: bf+sf +\RequirePackage{sectsty} +\allsectionsfont{\sffamily\boldmath} +% Also for descrptions +\renewcommand*\descriptionlabel[1]{\hspace\labelsep + \normalfont\bfseries\sffamily #1} + + +% Title/Author/affiliations +\def\@institute{No institute given.} +\newcommand{\institute}[1]{\gdef\@institute{#1}} +\newcommand{\authorrunning}[1]{\gdef\IACR@runningauthors{#1}} +\newcommand{\titlerunning}[1]{\gdef\IACR@runningtitle{#1}} + +\newcounter{IACR@author@cnt} +\newcounter{IACR@inst@cnt} +\newif\if@IACR@autoinst +\@IACR@autoinsttrue +\def\IACR@author@last{0} + +\renewcommand\maketitle{\par + \begingroup + \renewcommand\thefootnote{\@fnsymbol\c@footnote}% + \long\def\@makefntext##1{\parindent 1em\noindent + \hb@xt@1.8em{% + \hss\@textsuperscript{\normalfont\@thefnmark}}##1}% + \newpage + \global\@topnum\z@ % Prevents figures from going at top of page. + \@maketitle + \thispagestyle{title}\@thanks + \endgroup + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@maketitle\relax + \global\let\@thanks\@empty +% \global\let\@author\@empty + \global\let\@date\@empty +% \global\let\@title\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax +} +\def\@maketitle{% + % Count authors and affiliations + \setcounter{IACR@author@cnt}{1}% + \setcounter{IACR@inst@cnt}{1}% + \setbox0\hbox{\def\thanks##1{\global\@IACR@autoinstfalse}\def\inst##1{\global\@IACR@autoinstfalse}\def\and{\stepcounter{IACR@author@cnt}}\@author}% + \setbox0\hbox{\def\and{\stepcounter{IACR@inst@cnt}}\@institute}% + \xdef\IACR@author@last{\theIACR@author@cnt}% + \edef\IACR@inst@last{\theIACR@inst@cnt}% + \ifnum\IACR@author@last=\IACR@inst@last\else\@IACR@autoinstfalse\fi + \ifnum\IACR@author@last=1 \@IACR@autoinstfalse\fi + \newpage + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks + {\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% + {\LARGE \bfseries\sffamily\boldmath \@title\par} + \ifdefined\@subtitle\vskip .5em{\large\sffamily\bfseries\@subtitle\par}\fi}% + \vskip 1.5em% + {\large + \lineskip .5em% + \if@submission + Anonymous Submission + \else + \setcounter{IACR@author@cnt}{1}% + \def\and{\if@IACR@autoinst\inst{\theIACR@author@cnt} \fi + \stepcounter{IACR@author@cnt}% + \ifnum\theIACR@author@cnt=\IACR@author@last\unskip\space and \ignorespaces\else\unskip, \ignorespaces\fi} + \@author\if@IACR@autoinst\inst{\theIACR@author@cnt}\fi + \vskip 1em\par + \small + \setcounter{IACR@author@cnt}{1}% + \def\and{\par\stepcounter{IACR@author@cnt}$^\theIACR@author@cnt$~} + \ifnum\IACR@inst@last>1 $^1$~\fi + \@institute + \fi + }% + \end{center}% + \par + \vskip 1.5em} + +\def\IACR@runningauthors{ + \def\thanks##1{}% + \def\inst##1{}% + \def\fnmsep{}% + \def\\{}% + \def\footnote##1{}% + \setcounter{IACR@author@cnt}{1}% + \def\and{\stepcounter{IACR@author@cnt}% + \ifnum\theIACR@author@cnt=\IACR@author@last\unskip\space and \ignorespaces\else\unskip, \ignorespaces\fi} + \@author} + +\def\IACR@runningtitle{% + \def\thanks##1{}% + \def\fnmsep{}% + \def\\{}% + \def\footnote##1{}% + \@title} + +\def\author{\@ifnextchar[{\IACR@@@author}{\IACR@@author}} +\def\IACR@@@author[#1]#2{\authorrunning{#1}\gdef\@author{#2}} +\def\IACR@@author#1{\gdef\@author{#1}} + +\if@submission +\gdef\@author{Anonymous Submission to \publname} +\renewcommand{\author}[2][]{} +\renewcommand{\authorrunning}[1]{} +\renewcommand{\institute}[2][]{} +\fi + + +\def\title{\@ifnextchar[{\IACR@@@title}{\IACR@@title}} +\def\IACR@@@title[#1]#2{\gdef\@title{#2}\titlerunning{#1}} +\def\IACR@@title#1{\gdef\@title{#1}} + +\newcommand{\subtitle}[1]{\gdef\@subtitle{#1}} + +\newcommand{\inst}[1]{\unskip$^{#1}$} +\def\fnmsep{\unskip$^,$} + + +% Head/foot +\RequirePackage{fancyhdr} +\RequirePackage{graphicx} +\fancypagestyle{title}{% +\fancyhf{} % clear all header and footer fields +\if@submission\else\if@preprint\else +\fancyfoot[L]{\small Licensed under \href{http://creativecommons.org/licenses/by/4.0/}{Creative Commons License CC-BY 4.0.}\\ +\publname{} Vol.~\IACR@vol, No.\IACR@no, pp.\IACR@fp---\IACR@lp, \href{https://doi.org/\IACR@DOI}{DOI:\IACR@DOI}} +\fancyfoot[R]{\includegraphics[height=2ex]{CC-by}} +\if@loadhr + \hypersetup{pdfcopyright={Licensed under Creative Commons License CC-BY 4.0.}} + \hypersetup{pdflicenseurl={http://creativecommons.org/licenses/by/4.0/}} + \hypersetup{pdfsubject={IACR Transactions on Symmetric Cryptology}} + \hypersetup{pdflang=en} +\fi +\fi\fi +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\footrulewidth}{0pt}} +\fancyhf{} % clear all header and footer fields +\fancyhead[RO,LE]{\thepage} +\fancyhead[RE]{\IACR@runningtitle} +\fancyhead[LO]{\IACR@runningauthors} +\renewcommand{\markboth}[2]{} +\pagestyle{fancy} + +\def\subtitle#1{\gdef\@subtitle{#1}} + +%Abstract style, keywords +\def\@IACR@keywords{No keywords given.} + +\def\keywords{\@ifnextchar[{\IACR@@@keywords}{\IACR@@keywords}} +\def\IACR@@@keywords[#1]#2{\gdef\@IACR@PDFkeywords{#1}\gdef\@IACR@keywords{#2}} +\def\IACR@@keywords#1{\gdef\@IACR@keywords{#1}} + +\renewenvironment{abstract}{% + \small\quotation\setlength{\parindent}{0pt}\noindent + \textbf{\textsf{Abstract.}}} + {\smallskip\par\textbf{\textsf{Keywords:}} + \def\and{\unskip\space\textperiodcentered\space\ignorespaces}\@IACR@keywords + \endquotation% + \if@loadhr + %% PDF keywords + \def\and{, }% + \def\thanks##1{}% + \def\footnote##1{}% + \def\inst##1{}% + \def\fnmsep{}% + \def\\{}% + \def\zap@comma@space##1 ,##2{% + ##1% + \ifx##2\@empty\else, \expandafter\zap@comma@space\fi + ##2} + \ifdefined\@IACR@PDFkeywords + \hypersetup{pdfkeywords=\@IACR@PDFkeywords} + \else + \protected@edef\@tmp{\expandafter\@IACR@keywords} + \protected@edef\@tmp{\expandafter\zap@comma@space\@tmp{} ,\@empty} + \hypersetup{pdfkeywords=\@tmp} + \fi + %% PDF author + \def\zap@one,##1{} + \def\zap@last##1,##2{\ifx##1\@empty\else\space and ##1\expandafter\zap@one\fi} + \def\zap@last@comma##1,##2,##3{% + ##1% + \ifx##3\@empty% + \expandafter\zap@last\else + ,\expandafter\zap@last@comma\fi% + ##2,##3} + \def\zap@dbl@space##1 ##2{% + ##1% + \ifx##2\@empty\else\space\expandafter\zap@dbl@space##2\fi} + \protected@edef\@tmp{\expandafter\@author} + % \protected@edef\@tmp{\expandafter\IACR@runningauthors} + \protected@edef\@tmp{\expandafter\zap@last@comma\@tmp,\@empty,\@empty} + \protected@edef\@tmp{\expandafter\zap@comma@space\@tmp{} ,\@empty} + \protected@edef\@tmp{\expandafter\zap@dbl@space\@tmp{} \@empty} + \hypersetup{pdfauthor=\@tmp} + %% PDF title + \hypersetup{pdftitle=\IACR@runningtitle} + \fi +} + + +% Hyperref +\if@loadhr + \RequirePackage{xcolor} + \RequirePackage{etoolbox} + \AtEndPreamble{ + \@ifpackageloaded{hyperref}{}{\usepackage{hyperref}} + \@ifpackageloaded{hyperxmp}{}{\usepackage{hyperxmp}} + \hypersetup{colorlinks=true, + citecolor=black!70!green, + linkcolor=black!70!red} + } + \setcounter{tocdepth}{2} +\fi +% autoref: capitals for Sections, and adding Algorithm +\def\equationautorefname{Equation}% +\def\footnoteautorefname{footnote}% +\def\itemautorefname{item}% +\def\figureautorefname{Figure}% +\def\tableautorefname{Table}% +\def\partautorefname{Part}% +\def\appendixautorefname{Appendix}% +\def\chapterautorefname{Chapter}% +\def\sectionautorefname{Section}% +\def\subsectionautorefname{Subsection}% +\def\subsubsectionautorefname{Subsubsection}% +\def\paragraphautorefname{paragraph}% +\def\subparagraphautorefname{subparagraph}% +\def\FancyVerbLineautorefname{line}% +\def\theoremautorefname{Theorem}% +\def\pageautorefname{page}% +\def\algorithmautorefname{Algorithm} + +% AMS math +\RequirePackage{amsmath,amssymb,amsthm} +\RequirePackage{mathtools} +\theoremstyle{definition} +\newtheorem{definition}{Definition} +\newtheorem{example}{Example} +\newtheorem{exercise}{Exercise} +\newtheorem{property}{Property} +\newtheorem{question}{Question} +\newtheorem{solution}{Solution} + +\theoremstyle{plain} +\newtheorem{theorem}{Theorem} +\newtheorem{proposition}{Proposition} +\newtheorem{problem}{Problem} +\newtheorem{lemma}{Lemma} +\newtheorem{conjecture}{Conjecture} +\newtheorem{corollary}{Corollary} +\newtheorem*{claim}{Claim} + +\theoremstyle{remark} +\newtheorem{remark}{Remark} +\newtheorem{note}{Note} +\newtheorem{case}{Case} + +\theoremstyle{plain} + +%Emulate LLNCS spnewtheorem +\if@spthm +\def\spnewtheorem{\@ifstar{\IACR@spstar}{\IACR@sp}} +\def\IACR@spstar#1#2#3#4{\newtheorem*{#1}{#2}} +\def\IACR@sp#1{\@ifnextchar[{\IACR@sp@b{#1}}{\IACR@sp@a{#1}}} +\def\IACR@sp@a#1#2[#3]#4#5{\newtheorem{#1}{#2}[#3]} +\def\IACR@sp@b#1[#2]#3#4#5{\newtheorem{#1}[#2]{#3}} +\renewcommand{\pushQED}[1]{} +\fi + +% Floats and captions +\if@floatrow +\RequirePackage{floatrow} +\floatsetup[table]{style=Plaintop} +\RequirePackage{caption} +\captionsetup{labelfont={sf,bf}} +\else +\RequirePackage{float} +\newcommand\fs@iacrabove{% + % Swap \abovecaptionskip and \belowcaptionskip + \addtolength\abovecaptionskip{-\belowcaptionskip} + \addtolength\belowcaptionskip{\abovecaptionskip} + \addtolength\abovecaptionskip{-\belowcaptionskip} + \setlength\abovecaptionskip{-\abovecaptionskip} + \fs@plaintop% + \def\@fs@cfont{\sffamily\bfseries}} +\newcommand\fs@iacrbelow{% + \fs@plain% + \def\@fs@cfont{\sffamily\bfseries}} +\floatstyle{iacrabove} +\restylefloat{table} +\floatstyle{iacrbelow} +\restylefloat{figure} +\fi + +% Extra commands +\def\email{\@ifnextchar[{\IACR@@email}{\IACR@email}} +\if@loadhr +\def\IACR@@email[#1]#2{\href{mailto:#1}{\nolinkurl{#2}}} +\def\IACR@email#1{\href{mailto:#1}{\nolinkurl{#1}}} +\else +\RequirePackage{url} +\def\IACR@@email[#1]#2{\url{#2}} +\def\IACR@email#1{\url{#1}} +\fi + +% Line # for submission +\newcommand\linenomathWithnumbersforAMS{% + \ifLineNumbers +%% \ifx\@@par\@@@par\else + \ifnum\interlinepenalty>-\linenopenaltypar + \global\holdinginserts\thr@@ + \advance\interlinepenalty \linenopenalty + \ifhmode % v4.3 + \advance\predisplaypenalty \linenopenalty + \fi +%% \advance\postdisplaypenalty \linenopenalty + \advance\interdisplaylinepenalty \linenopenalty + \fi + \fi + \ignorespaces + } + +\if@submission +\RequirePackage[mathlines]{lineno} +\linenumbers +\def\linenumberfont{\normalfont\tiny\sffamily\color{gray}} + +% Taken from http://phaseportrait.blogspot.fr/2007/08/lineno-and-amsmath-compatibility.html +\newcommand*\patchAmsMathEnvironmentForLineno[1]{% + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname + \renewenvironment{#1}% + {\linenomathWithnumbersforAMS\csname old#1\endcsname}% + {\csname oldend#1\endcsname\endlinenomath}}% +\newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{% + \patchAmsMathEnvironmentForLineno{#1}% + \patchAmsMathEnvironmentForLineno{#1*}}% +\AtBeginDocument{% +%\patchBothAmsMathEnvironmentsForLineno{equation}% +\patchBothAmsMathEnvironmentsForLineno{align}% +\patchBothAmsMathEnvironmentsForLineno{flalign}% +\patchBothAmsMathEnvironmentsForLineno{alignat}% +\patchBothAmsMathEnvironmentsForLineno{gather}% +\patchBothAmsMathEnvironmentsForLineno{multline}% +} +\fi + +% Microtype +\RequirePackage{microtype} + +% Fonts +\usepackage[T1]{fontenc} +\usepackage{lmodern} diff --git a/doc/paper/ihsm_shaft_countermeasures_a.pdf b/doc/paper/ihsm_shaft_countermeasures_a.pdf new file mode 100755 index 0000000..6f1f857 Binary files /dev/null and b/doc/paper/ihsm_shaft_countermeasures_a.pdf differ diff --git a/doc/paper/ihsm_shaft_countermeasures_a.svg b/doc/paper/ihsm_shaft_countermeasures_a.svg new file mode 100755 index 0000000..1c89ced --- /dev/null +++ b/doc/paper/ihsm_shaft_countermeasures_a.svg @@ -0,0 +1,160 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/paper/ihsm_shaft_countermeasures_b.pdf b/doc/paper/ihsm_shaft_countermeasures_b.pdf new file mode 100755 index 0000000..9ad0f95 Binary files /dev/null and b/doc/paper/ihsm_shaft_countermeasures_b.pdf differ diff --git a/doc/paper/ihsm_shaft_countermeasures_b.svg b/doc/paper/ihsm_shaft_countermeasures_b.svg new file mode 100755 index 0000000..c6c3e29 --- /dev/null +++ b/doc/paper/ihsm_shaft_countermeasures_b.svg @@ -0,0 +1,174 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/paper/ihsm_shaft_countermeasures_c.pdf b/doc/paper/ihsm_shaft_countermeasures_c.pdf new file mode 100755 index 0000000..5e01be2 Binary files /dev/null and b/doc/paper/ihsm_shaft_countermeasures_c.pdf differ diff --git a/doc/paper/ihsm_shaft_countermeasures_c.svg b/doc/paper/ihsm_shaft_countermeasures_c.svg new file mode 100755 index 0000000..715b038 --- /dev/null +++ b/doc/paper/ihsm_shaft_countermeasures_c.svg @@ -0,0 +1,246 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/paper/rotohsm_paper.pdf b/doc/paper/rotohsm_paper.pdf index e1260c4..974af7b 100644 Binary files a/doc/paper/rotohsm_paper.pdf and b/doc/paper/rotohsm_paper.pdf differ diff --git a/doc/paper/rotohsm_paper.tex b/doc/paper/rotohsm_paper.tex index fb7c347..83846a9 100644 --- a/doc/paper/rotohsm_paper.tex +++ b/doc/paper/rotohsm_paper.tex @@ -1,6 +1,4 @@ -\documentclass[10pt,journal,a4paper]{IEEEtran} -\usepackage[english]{babel} -\usepackage[utf8]{inputenc} +\documentclass[nohyperref]{iacrtrans} \usepackage[T1]{fontenc} \usepackage[ backend=biber, @@ -12,74 +10,34 @@ ]{biblatex} \addbibresource{rotohsm.bib} \usepackage{amssymb,amsmath} -\usepackage{listings} \usepackage{eurosym} \usepackage{wasysym} \usepackage{amsthm} -\usepackage{tabularx} -\usepackage{multirow} -\usepackage{multicol} -\usepackage{tikz} -\usepackage{mathtools} -\DeclarePairedDelimiter{\ceil}{\lceil}{\rceil} -\DeclarePairedDelimiter{\paren}{(}{)} - -\usetikzlibrary{arrows} -\usetikzlibrary{chains} -\usetikzlibrary{backgrounds} -\usetikzlibrary{calc} -\usetikzlibrary{decorations.markings} -\usetikzlibrary{decorations.pathreplacing} -\usetikzlibrary{fit} -\usetikzlibrary{patterns} -\usetikzlibrary{positioning} -\usetikzlibrary{shapes} \usepackage[binary-units]{siunitx} \DeclareSIUnit{\baud}{Bd} \DeclareSIUnit{\year}{a} -\usepackage{hyperref} -\usepackage{tabularx} \usepackage{commath} \usepackage{graphicx,color} -\usepackage{ccicons} \usepackage{subcaption} -\usepackage{float} -\usepackage{footmisc} \usepackage{array} -\usepackage[underline=false]{pgf-umlsd} -\usetikzlibrary{calc} -%\usepackage[pdftex]{graphicx,color} -\usepackage{epstopdf} -\usepackage{pdfpages} -\usepackage{minted} % pygmentized source code +\usepackage{hyperref} \renewcommand{\floatpagefraction}{.8} \newcommand{\degree}{\ensuremath{^\circ}} \newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}} - -\usepackage{fancyhdr} -\fancyhf{} -\fancyfoot[C]{\thepage} -\newcommand{\includenotebook}[2]{ - \fancyhead[C]{Included Jupyter notebook: #1} - \includepdf[pages=1, - pagecommand={\thispagestyle{fancy}\section{#1}\label{#2_notebook}} - ]{resources/#2.pdf} - \includepdf[pages=2-, - pagecommand={\thispagestyle{fancy}} - ]{resources/#2.pdf} -} +\newcommand{\partnum}[1]{\texttt{#1}} \begin{document} -\title{Can't Touch This: Inerial HSMs Thwart Advanced Physical Attacks} -\author{Jan Götte} -\date{2020-12-20} +\title[Can't Touch This]{Inertial HSMs Thwart Advanced Physical Attacks} +\author{Jan Sebastian Götte \and Björn Scheuermann} +\institute{HIIG\\ \email{ihsm@jaseg.de} \and Björn Scheuermann \\ \email{scheuermann@informatik.hu-berlin.de}} +% FIXME keywords +\keywords{hardware security \and implementation \and smart cards \and electronic commerce} \maketitle -\section*{Abstract} - +\begin{abstract} In this paper, we introduce a novel countermeasure against physical attacks: Inertial hardware security modules (iHSMs). Conventional systems have in common that they try to detect attacks by crafting sensors responding to increasingly minute manipulations of the monitored security boundary or volume. Our approach is novel in that we reduce the @@ -89,6 +47,7 @@ the rotation are easily monitored with commercial MEMS accelerometers and gyrosc can easily be built from off-the-shelf parts by any university electronics lab, yet offers a level of security that is comparable to commercial HSMs. By building prototype hardware we have demonstrated solutions to the concept's engineering challenges. +\end{abstract} \section{Introduction} @@ -235,6 +194,18 @@ tangential velocity is low. Faster rotation can lessen the severity of this at t mechanical load but can never eliminate it. This effect can be alleviated in two ways: Either by adding additional tamper protection at the axis, or by having the HSM perform a compound rotation that has no fixed axis. +A beneficial side-effect of rotation is that an attacker trying to follow the motion would have to rotate around +the same axis. By choosing a suitable rotation frequency we can thus prevent an attacker from following the devices +motion since doing so would subject them to impractically large centrifugal forces. Essentially, this limits the +approximate maximum size and mass of an attacker based on an assumption on tolerable centrifugal force (see Appendix +\ref{sec_minimum_angular_velocity}). + +Large centrifugal acceleration at high speeds poses the engineering challenge of preventing rapid unscheduled +disassembly of the device, but it also creates an obstacle to any attacker trying to manipulate the device. +From a coarse calculation (Appendix \ref{sec_minimum_angular_velocity}) we conclude that even at moderate speeds (above +$\SI{500}{rpm}$), a manual attack is no longer possible and any attack would have to be carried out using either +computer control or precise mechanics. + In this paper we focus on rotating IHSMs for simplicity of construction. For our initial research, we are focusing on systems having a fixed axis of rotation due to their relative simplicity in prototype construction but we note the challenge of hardening the shaft against tampering. @@ -270,35 +241,56 @@ able to measure any external force applied to the IHSM's rotor and should alread manipulation. While the obvious choice to monitor rotation would be a tachometer such as a magnetic or opitical sensor attached to the -IHSM's shaft, this would be a poor choice in our application. Both optical and matgnetic sensors are susceptible to +IHSM's shaft, this would be a poor choice in our application. Both optical and magnetic sensors are susceptible to contact-less interference from outside. Instead, an accelerometer is a good component to serve as an IHSM's tamper -sensor. - -%%% - -First, for motion to effectively disincentivize tampering, the HSM has to move fairly fast. -If any point of the HSM's tamper sensing shell moves slow enough for a human to follow, that point becomes a weak spot. -For illustration, consider linear oscillating motion like that of a pendulum. -At its apex, the pendulum becomes stationary and an attacker could use that split second of the device not moving. +sensor. Modern fully intergrated MEMS accelerometers are very precise. By comparing acceleration measurements against a +model of the device's mechanical motion, deviations can quickly be detected. This limits an attacker's ability to tamper +with the device's motion. It may also allow remote monitoring of the device's mechanical components such as bearings. +Accelerometers are fast enough to capture vibrations, which can be used as an early warning sign of failing mechanical +components. % FIXME citation + +In a spinning IHSM, an accelerometer mounted at a known radius with its axis pointing radially will measure centrifugal +acceleration. Centrifugal acceleration rises linearly with radius, and with the square of frequency: $a=\omega^2 r$. For +a given target speed of rotation, the accelerometer's location has to be carefully chosen to maximize dynamic range. A +key point here is that for rotation speeds between $500$ and $\SI{1000}{rpm}$, centrifugal acceleration already becomes +very large at a radius of just a few $\si{\centi\meter}$. At $\SI{1000}{rpm}=\SI{17}{\hertz}$ at a +$\SI{10}{\centi\meter}$ radius acceleration already is above $\SI{1000}{\meter\per\second}$ or $100\,g$. Off-axis +performance of commercial accelerometers is usually in the order of $\SI{1}{\percent}$ so this large acceleration will +feed through into all accelerometer axes, even those that are tangential to the rotation. It also means that we either +have to place the accelerometer close to the axis or we are limited to a small selection of high-$g$ accelerometers +mostly used in automotive applications. + +To evaluate the feasibility of accelerometers as tamper sensors we can use a simple benchmark: Let us assume that an +IHSM is spinning at $\SI{1000}{rpm}$ and that we wish to detect any attempt to brake it below $\SI{500}{rpm}$. The +difference in centrifugal acceleration will be a factor of $\frac{\omega_2^2}{\omega_1^2}=4$. This results in a +factor-$4$ difference in absolute acceleration that our accelerometer must be able to detect. If we choose our +accelerometer's location to maximize its dynamic range, any commercial MEMS accelerometer should suffice for this degree +of accuracy. For rapid deceleration, commercial accelerometers will be much more sensitive as effects of long-term drift +can be ignored. If we wish to also detect very slow deceleration, we have to take into account the accelerometer's drift +characteristics. + +% TODO review below paragraph +In Section~\ref{sec_accel_meas} below we conduct an empirical evaluation of a commercial automotive high-$g$ +accelerometer for braking detection in our prototype IHSM. +In Appendix~\ref{sec_degrees_of_freedom} we consider accelerometer configurations and we conclude that one three-axis +accelerometer each in the rotor and in the stator are a good baseline configuration. In general, the system will be more +sensitive to attacks if we over-determine the system of equations describing its motion by using more sensors than +necessary. -Second, a spinning HSM is potentially more compact than some alternatives like a pendulum or more exotic concepts such -as an HSM on wheels. Its main disadvantage is its circular envelope: When using components such as standard server -hardware for its payload, these components likely come in a rectangular form factor leading to dead space inside the -HSM. Mounting the HSM in a standard rackmount enclosure will also lead to significant dead space around the HSM. An -``vibrating'' HSM with a small amplitude of oscillation might potentially lead to a more compact solution, but this -compactness would come at increased engineering complexity and increased material stresses. +\subsection{Mechanical layout} -Third and finally, constant rotation leads to a predictable, constant acceleration anywhere in the rotating part. This -allows the use of an accelerometer for tamper detection with minimal signal post-processing. +With our IHSM's components taken care of, what remains to be decided is how to put together these individual components +into a complete device. A basic spinning HSM might look like shown in Figure~\ref{fig_schema_one_axis}. Shown are the +axis of rotation, an accelerometer on the rotating part used to detect braking, the protected payload and the area +covered by the rotating tamper detection mesh. -A beneficial side-effect of spinning the HSM is that an attacker trying to follow the motion would have to rotate around -the same axis, subjecting them to very large centrifugal accleration. -This allows us to limit the approximate maximum size and mass of an attacker using an assumption on tolerable -centrifugal force (see Appendix \ref{sec_minimum_angular_velocity}). +A key observation is that we only have to move the tamper protection mesh, not the entire contents of the HSM. +The HSM's payload and with it most of the HSM's mass can be stationary. This reduces the moment of inertia of the +moving part. -A basic spinning HSM might look like shown in Figure \ref{fig_schema_one_axis}. Shown are the axis of rotation, an -accelerometer on the rotating part used to detect braking, the protected payload and the area covered by the rotating -tamper detection mesh. +This basic schema accepts a weak spot at the point where the shaft penetrates the spinning mesh. This trade-off makes +for a simple mechanical construction and allows power and data connections to the stationary payload through a hollow +shaft. \begin{figure} \center @@ -308,112 +300,99 @@ tamper detection mesh. \label{fig_schema_one_axis} \end{figure} -\section{Using accelerometers as rotation sensors} - -In a rotating reference frame, centrifugal force is proportional to the square of angular velocity and proportional to -distance from the axis of rotation. We can exploit this fact to use an accelerometer as a sensor that detects any -disturbance to the HSM's rotation. We place the accelerometer at a known distance from the axis of rotation. When the -axis of rotation is vertical, during constant rotation tangential acceleration will be zero and acceleration along the -axis of rotation will be $\SI{1}{\g}$. Centrifugal acceleration will be constant. - -Large centrifugal acceleration at high speeds poses the engineering challenge of preventing rapid unscheduled -disassembly of the device, but it also creates an obstacle to any attacker trying to manipulate the device. -A key observation is that we only have to move the tamper protection mesh, not the entire contents of the HSM. -The HSM's payload and with it most of the HSM's mass can be stationary. -This reduces the moment of inertia of the moving part and it means that we can use cables for power and data connections -to the payload. - -From a coarse calculation (Appendix \ref{sec_minimum_angular_velocity}) we conclude that even at moderate speeds (above -$\SI{500}{rpm}$), a manual attack is no longer possible and any attack would have to be carried out using either -computer control or precise mechanics. - -In Appendix \ref{sec_degrees_of_freedom} we consider sensor configurations and we conclude that one three-axis -accelerometer each in the rotor and in the stator are a good baseline configuration. In general, the system will be more -sensitive to attacks if we over-determine the system of equations describing its motion by using more sensors than -necessary. - -\subsection{Mechanical layout} - -Thinking about the concrete construction of our mechanical HSM, the first challenge is mounting both mesh and payload on -a single shaft. The simplest way we found to mount a stationary payload inside of a spinning security mesh is a hollow -shaft. The payload can be mounted on a fixed rod threaded through this hollow shaft along with wires for power and -data. The shaft is a weak spot of the system, but this weak spot can be alleviated through either careful construction -or a second layer of rotating meshes with a different axis of rotation. Configurations that do not use a hollow-shaft -motor are possible, but may require additional bearings to keep the stator from vibrating. - -The next design choice we have to make is the physical structure of the security mesh. The spinning mesh must be -designed to cover the entire surface of the payload, but compared to a traditional HSM it suffices if it sweeps over -every part of the payload once per rotation. This means we can design longitudinal gaps into the mesh that allow outside -air to flow through to the payload. In traditional boundary-sensing HSMs, cooling of the payload processor is a serious -issue since any air duct or heat pipe would have to penetrate the HSM's security boundary. This problem can only be -solved with complex and costly siphon-style constructions, so in commercial systems heat conduction is used -exclusively~\cite{isaacs2013}. This limits the maximum power dissipation of the payload and thus its processing power. -Our setup allows direct air cooling of regular heatsinks. This greatly increases the maximum possible power dissipation -of the payload and unlocks much more powerful processing capabilities. In an evolution of our design, the spinning mesh -could even be designed to \emph{be} a cooling fan. - -\subsection{Spinning mesh power and data transmission} - -On the electrical side, the idea of a security mesh spinning at more than $\SI{500}{rpm}$ leaves us with a few -implementation challenges. Since the spinning mesh must be monitored for breaks or short circuits continuously, we need -both a power supply for the spinning monitoring circuit and a data link to the stator. - -We found that a bright lamp shining at a rotating solar panel is a good starting point. In contrast to e.g.\ slip -rings, this setup is mechanically durable at high speeds and it also provides reasonable output power (see Appendix -\ref{sec_energy_calculations} for an estimation of power consumption). A battery may not provide a useful lifetime -without power-optimization. Likewise, an energy harvesting setup may not provide enough current to supply peak demand. - -Since the monitoring circuit uses little current, power transfer efficiency is not important. On the other hand, cost -may be a concern in a production device. Here it may prove worthwhile to replace the solar cell setup with an extra -winding on the rotor of the BLDC motor driving the spinning mesh. This motor is likely to be a custom part, so adding -an extra winding is unlikely to increase cost significantly. More traditional inductive power transfer may also be an -option if it can be integrated into the mechanical design. - -Besides power, the data link between spinning mesh and payload is critical to the HSM's design. This link is used to -transmit the occassional status report along with a low-latency alarm trigger (``heartbeat'') signal from mesh to payload. -As we will elaborate in Section~\ref{sec_proto} a simple infrared optical link turned out to be a good solution for this -purpose. - -\subsection{Tamper detection} +The spinning mesh must be designed to cover the entire surface of the payload, but in contrast to a traditional HSM it +suffices if it sweeps over every part of the payload once per rotation. This means we can design longitudinal gaps into +the mesh that allow outside air to flow through to the payload. In traditional boundary-sensing HSMs, cooling of the +payload processor is a serious issue since any air duct or heat pipe would have to penetrate the HSM's security +boundary. This problem can only be solved with complex and costly siphon-style constructions, so in commercial systems +heat conduction is used exclusively~\cite{isaacs2013}. This limits the maximum power dissipation of the payload and thus +its processing power. Our setup allows direct air cooling of regular heatsinks. This greatly increases the maximum +possible power dissipation of the payload and unlocks much more powerful processing capabilities. In an evolution of +our design, the spinning mesh could even be designed to \emph{be} a cooling fan. \section{Attacks} \label{sec_attacks} After outlining the basic mechanical design of an inertial HSM above, in this section we will detail possible ways to -attack it. Fundamentally, attacks on an inertial HSM are the same as those on a traditional HSM since the tamper -detection mesh is the same. Only, in the inertial HSM any attack on the mesh has to be carried out while the mesh is -rotating, which for most types of attack will require some kind of CNC attack robot moving in sync with it. +attack it. At the core of an IHSM's defenses is the same security mesh that is also used in traditional HSMs. This means +that in the end an attacker will have to perform the same steps they would have to perform to attack a traditional HSM. +Only to attack an IHSM, assuming that the braking detection system works they will have to perform these steps with a +tool that follows the HSMs rotation at high speed. This may require specialized mechanical tools, CNC actuators or +even a contactless attack using a laser, plasma jet or water jet. + +\subsection{Mechanical weak spots} + +The tamper defense of an IHSM rests on the security mesh moving too fast to tamper. Depending on the type of motion +used, the meshes speed may vary by location and over time. Our example configuration of a rotating mesh can keep moving +continuously, so it does not have any time-dependent weak spots. It does however have a weak spot at its axis of +rotation, at the point where the shaft penetrates the mesh. The meshes tangential velocity decreases close to the shaft, +and the shaft itself may allow an attacker to insert tools such as probes into the device through the opening it +creates. + +This issue is related to the issue conventional HSMs also face with their power and data connections. In conventional +HSMs, power and data are routed into the enclosure through the PCB or flat flex cables sandwiched in between +security mesh foil layers. By using a thin substrate and by creating a meandering path by folding the interconnect +substrate/security mesh layers several times, in traditional HSMs this interface rarely is a mechanical weak spot. In +inertial HSMs, careful engineering is necessary to achieve the same effect. Figure~\ref{shaft_cm} shows variations +of the shaft interface of increasing level of complexity. -\subsection{Attacking at the axis of rotation} +\begin{figure} + \begin{subfigure}[t]{0.3\textwidth} + \center + \includegraphics[width=4cm]{ihsm_shaft_countermeasures_a.pdf} + \caption{Cross-sectional view of the basic configuration with no special protection of the shaft. Red: Moving + mesh -- Black: Stationary part.} + \label{shaft_cm_a} + \end{subfigure} + \hfill + \begin{subfigure}[t]{0.3\textwidth} + \center + \includegraphics[width=4cm]{ihsm_shaft_countermeasures_b.pdf} + \caption{An internal counter-rotating disc greatly decreases the space available to attackers at the expense of + another moving part and a second moving monitoring circuit.} + \label{shaft_cm_a} + \end{subfigure} + \hfill + \begin{subfigure}[t]{0.3\textwidth} + \center + \includegraphics[width=4cm]{ihsm_shaft_countermeasures_c.pdf} + \caption{A second moving tamper detection mesh also enables more complex topographies.} + \label{shaft_cm_a} + \end{subfigure} + \caption{Mechanical countermeasures to attacks through or close to a rotating IHSM's shaft.} + \label{shaft_cm} +\end{figure} -\subsection{Attacks on the mesh} +\subsection{Attacking the mesh in motion} -There are two locations where one can attack a tamper-detection mesh. On one hand, the mesh itself can be tampered with. -This includes bridging its traces to allow for a hole to be cut. The other option is to tamper with the monitoring -circuit itself to prevent a damaged mesh from triggering an alarm and causing the HSM to erase its -contents~\cite{dexter2015}. Attacks in both locations are electronic attacks, i.e. they require electrical contact to +To disable the mesh itself, an attacker can choose two paths. One is to attack the mesh itself, for example by bridging + its traces to allow for a hole to be cut. The other option is to tamper with the monitoring +circuit to prevent a damaged mesh from triggering an alarm~\cite{dexter2015}. + +Attacks in both locations are electronic attacks, i.e. they require electrical contact to parts of the circuit. Traditionally, this contact is made by soldering or by placing a probe such as a thin needle. We -consider this contact infeasible to be performed on an object spinning at high speed without a complex setup that -rotates along with the object or that involves ion beams, electron beams or liquids. Thus, we consider them to be -practically infeasible outside of a well-funded, special-purpose laboratory. +consider this type of attack hard to perform on an object spinning at high speed. Possible remaining attack avenues may +be to rotate an attack tool in sync with the mesh, or to use a laser or ion beam fired at the mesh to cut traces or +carbonize parts of the substrate to create electrical connections. Encapsulating the mesh in a potting compound and +shielding it with a metal enclosure as is common in traditional HSMs will significantly increase the complexity of such +attacks. \subsection{Attacks on the rotation sensor} Instead of attacking the mesh in motion, an attacker may also try to first stop the rotor. To succeed, they would need -to fool the rotor's MEMS accelerometer. An electronic attack on the sensor or the monitoring microcontroller would be no -easier than directly bridging the mesh traces. +to falsify the rotor's MEMS accelerometer measurements. We can disregard electronic attacks on the sensor or the +monitoring microcontroller because they would be no easier than attacking the mesh traces. What remains would be +physical attacks of the accelerometer's sensing mechanism. -MEMS accelerometers usually use a cantilever design, where a proof mass moves a cantilever whose precise position can be +MEMS accelerometers usually use a cantilever design, where a proof mass moves a cantilever whose precise position is measured electronically. A topic of recent academic interest have been acoustic attacks tampering with these -mechanics~\cite{trippel2017}. In the authors' estimate these attacks are too hard to control to be practically useful -against an inertial HSM. +mechanics~\cite{trippel2017}, but such attacks do not yield sufficient control to precisely falsify sensor readings. -A possible way to attack the accelerometer inside an inertial HSM may be to first decapsulate it using laser ablation -synchronized with the device's rotation. Then, a fast-setting glue such as a cyanoacrylate could be deposited on the -moving MEMS parts, locking them in place. To mitigate this type of attack the accelerometer should be mounted in a -shielded place inside the security envelope. Further, this attack can only work if the rate of rotation and thus the -expected accelerometer readings are constant. If the rate of rotation is set to vary over time this type of attack is -quickly detected. In Appendix \ref{sec_degrees_of_freedom} we outline the constraints on sensor placement. +A possible more invasive attack may be to first decapsulate the sensor MEMS using laser ablation synchronized with the +device's rotation. Then, a fast-setting glue such as a cyanoacrylate could be deposited on the MEMS, locking the +mechanism in place. This type of attack can be mitigated by mounting the accelerometer in a shielded location inside the +security envelope and by varying the rate of rotation over time. In Appendix~\ref{sec_degrees_of_freedom} we outline +some constraints on sensor placement. \subsection{Attacks on the alarm circuit} @@ -421,81 +400,80 @@ Besides trying to deactivate the tamper detection mesh, an electronic attack cou inside the stationary payload, or the communication link between rotor and payload. The link can be secured using a cryptographically secured protocol like one would use for wireless radio links along with a high-frequency heartbeat message. The alarm circuitry has to be designed such that it is entirely contained within the HSM's security envelope. -Like in conventional HSMs it has to be built to either tolerate or detect environmental attacks such as ones using -temperature, ionizing radiation, lasers, supply voltage variations, ultrasound or other vibration and gases or liquids. -Conventionally, incoming power rails are filtered thoroughly to prevent electrical attacks and other types of attacks -are prevented by sensors that thrigger an alarm. - -In an inertial HSM, the mesh monitoring circuit's tamper alarm is transmitted from rotor to stator through a wireless -link. Since an attacker may wirelessly spoof this link, it must be cryptographically secured. It also must be -bidirectional to allow the alarm signal receiver to verify link latency: If it were unidirectional, an attacker could -act as a Man-in-the-Middle and replay the mesh's authenticated ``no alarm'' signal at slightly below real-time speed -(say at $\SI{99}{\percent}$ speed). The receiver would not be able to distinguish between this attack and ordinary -deviations in the transmitter's local clock frequency. Thus, after some time the attacker can simply stop the rotor and -break the mesh while replaying the leftover recorded ``no alarm'' signal. Given the frequency stability of commercial -crystals, this would yield the attacker several seconds of undisturbed attack time per hour of recording time. +Like in conventional HSMs it has to be built to either tolerate or detect environmental attacks using sensors for +temperature, ionizing radiation, laser radiation, supply voltage variations, ultrasound or other vibration and gases or +liquids. If a wireless link is used between the IHSM's rotor and stator, this link must be cryptographically secured. +To prevent replay attacks this link must be bidirectional so link latency can be measured continuously. +% If it were unidirectional, an attacker could +% act as a Man-in-the-Middle and replay the mesh's authenticated ``no alarm'' signal at slightly below real-time speed +% (say at $\SI{99}{\percent}$ speed). The receiver would not be able to distinguish between this attack and ordinary +% deviations in the transmitter's local clock frequency. Thus, after some time the attacker can simply stop the rotor and +% break the mesh while replaying the leftover recorded ``no alarm'' signal. Given the frequency stability of commercial +% crystals, this would yield the attacker several seconds of undisturbed attack time per hour of recording time. \subsection{Fast and violent attacks} A variation of the above attacks on the alarm circuitry is to simply destroy the part of the HSM that erases data in -response to tampering before it can finish its job. This attack could use a tool such as a large hammer or a gun. -Mitigations for this type of attack include potting the payload inside a mechanically robust enclosure. Additionally, -the integrity of the entire alarm signalling chain can be checked continuously using a cryptographic heartbeat protocol. -A simple active-high or active-low alarm signal as it is used in traditional HSMs cannot be considered fail-safe in this -scenario as such an attack may well short-circuit or break PCB traces. +response to tampering before it can perform its job using a tool such as a large hammer or a gun. To mitigate this +type of attack, the HSM's tamper response circuitry must be mechanically robust enough to withstand an attack for long +enough to carry out its function or else to reliably destory the payload during an attack. \section{Prototype implementation} \label{sec_proto} -After elaborating the design principles of inertial HSMs and researching potential attack vectors we have validated -these theoretical studies by implementing a prototype rotary HSM. The main engineering challenges we solved in our -prototype are: +As we elaboreated above, the mechanical component of an IHSM significantly increases the complexity of any successful +attack even when implemented using only common, off-the-shelf parts. In view of this amplification of design security we +have decided to validate our theoretical studies by implementing a prototype IHSM. The main engineering challenges we +set out to solve in this prototype were: \begin{enumerate} - \item Fundamental mechanical design suitable for rapid prototyping that can withstand a rotation of $\SI{500}{rpm}$. + \item Fundamental mechanical design suitable for rapid prototyping that can withstand at least $\SI{500}{rpm}$. \item Automatic generation of security mesh PCB layouts for quick adaption to new form factors. \item Non-contact power transmission from stator to rotor. \item Non-contact bidirectional data communication between stator and rotor. \end{enumerate} +We will outline our findings on these challenges one by one in the following paragraphs. + \subsection{Mechanical design} -We sized our prototype to have space for up to two full-size Raspberry Pi boards. Each one of these boards is already -more powerful than an ordinary HSM, but they are small enough to simplify our prototype's design. For low-cost -prototyping we designed our prototype to use printed circuit boards as its main structural material. The interlocking -parts were designed in FreeCAD as shown in Figure \ref{proto_3d_design}. The mechanical designs were exported to KiCAD -for electrical design before being sent to a commercial PCB manufacturer. Rotor and stator are built from interlocking, -soldered PCBs. The components are mounted to a $\SI{6}{\milli\meter}$ brass tube using FDM 3D printed flanges. The rotor -is driven by a small hobby quadcopter motor. +We sized our prototype to have space for up to two full-size Raspberry Pi boards for an approximation of a traditional +HSM's processing capabilities. We use printed circuit boards as the main structural material for the rotating part, and +2020 aluminium extrusion for its mounting frame. Figure~\ref{proto_3d_design} shows the rotor's mechanical PCB designs +in FreeCAD. The design uses a $\SI{6}{\milli\meter}$ brass tube as its shaft, which is already sufficiently narrow to +pose a challenge to an attacker. The rotor is driven by a small hobby quadcopter motor. Our prototype incorporates a +functional PCB security mesh. As we observed previously, this mesh only needs to cover every part of the system once per +revolution, so we designed the longituninal PCBs as narrow strips to save weight. -Security is provided by a PCB security mesh enveloping the entire system and extending to within a few millimeters of -the shaft. For security it is not necessary to cover the entire circumference of the module with mesh, so we opted to -use only three narrow longitudinal struts to save weight. +\subsection{PCB security mesh generation} -To mount the entire HSM, we chose to use ``2020'' modular aluminium profile. +Our proof-of-concept security mesh covers a total of five interlocking PCBs (cf.\ Figure~\ref{mesh_gen_sample}). A sixth +PCB contains the monitoring circuit and connects to these mesh PCBs. To speed up design iterations, we automated the +generation of this security mesh using a plugin for the KiCAD EDA +suite\footnote{\url{https://blog.jaseg.de/posts/kicad-mesh-plugin/}}. Figure~\ref{mesh_gen_viz} visualizes the mesh +generation process. First, the target area is overlaid with a grid. Then, the algorithm produces a randomized tree +covering the grid. Finally, individual mesh traces are then traced according to a depth-first search through this tree. +We consider the quality of the plugin's output sufficient for practical applications. Along with FreeCAD's KiCAD StepUp +plugin, this results in an efficient toolchain from mechanical CAD design to production-ready PCB files. \begin{figure} - \center - \includegraphics[height=7cm]{proto_3d_design.jpg} - \caption{The 3D CAD design of the prototype.} - \label{proto_3d_design} + \begin{subfigure}{0.45\textwidth} + \center + \includegraphics[height=7cm]{proto_3d_design.jpg} + \caption{The 3D CAD design of the prototype.} + \label{proto_3d_design} + \end{subfigure} + \hfill + \begin{subfigure}{0.45\textwidth} + \vfil + \includegraphics[width=6cm]{mesh_scan_crop.jpg} + \vfil + \caption{Part of the security mesh PCB we produced with our toolchain for the prototype HSM.} + \label{mesh_gen_sample} + \end{subfigure} + \caption{Our prototype IHSM's PCB security mesh design} \end{figure} -\subsection{PCB security mesh generation} - -The security mesh covers a total of five interlocking PCBs. A sixth PCB contains the monitoring circuit and connects to -these mesh PCBs. To allow us to quickly iterate our design without manually re-routing several large security meshes -for every mechanical chage we wrote a plugin for the KiCAD EDA suite that automatically generates parametrized security -meshes. When KiCAD is used in conjunction with FreeCAD through FreeCAD's KiCAD StepUp plugin, this ends up in an -efficient toolchain from mechanical CAD design to security mesh PCB gerber files. The mesh generation plugin can be -found at its website\footnote{\url{https://blog.jaseg.de/posts/kicad-mesh-plugin/}}. The meshes it produces have a -practical level of security in our application. - -The mesh generation process starts by overlaying a grid on the target area. It then produces a randomized tree covering -this grid. The individual mesh traces are then traced along a depth-first search through this tree. A visualization of -the steps is shown in Figure \ref{mesh_gen_viz}. A sample of the production results from our prototype is shown in -Figure \ref{mesh_gen_sample}. - \begin{figure} \center \includegraphics[width=9cm]{mesh_gen_viz.pdf} @@ -505,67 +483,57 @@ Figure \ref{mesh_gen_sample}. \label{mesh_gen_viz} \end{figure} -\begin{figure} - \center - \includegraphics[width=6cm]{mesh_scan_crop.jpg} - \caption{A section of the security mesh PCB we produced with our toolchain for the prototype HSM.} - \label{mesh_gen_sample} -\end{figure} - -\subsection{Data transmission through rotating joint} - -With the mesh done, the next engineering challenge was the mesh monitoring data link between rotor and stator. As a -baseline solution, we settled on a $\SI{115}{\kilo\baud}$ UART signal sent through a simple bidirectional infrared link. -In the transmitter, the UART TX line on-off modulates a $\SI{920}{\nano\meter}$ IR LED through a common-emitter driver -transistor. In the receiver, an IR PIN photodiode reverse-biased to $\frac{1}{2}V_\text{CC}$ is connected to a -reasonably wideband transimpedance amplifier (TIA) with a $\SI{100}{\kilo\ohm}$ transimpedance. As shown in Figure -\ref{photolink_schematic}, the output of this TIA is fed through another $G=100$ amplifier whose output is then squared -up by a comparator. We used an \texttt{MCP6494} quad CMOS op-amp. At a specified $\SI{2}{\milli\ampere}$ current -consumption it is within our rotor's power budget, and its Gain Bandwidth Product of $\SI{7.5}{\mega\hertz}$ yields a -useful transimpedance in the photodiode-facing TIA stage. - -To reduce the requirements on power transmission to the rotor, we have tried to reduce power consumption of the -rotor-side receiver/transmitter pair trading off stator-side power consumption. One part of this is that we use -a wide-angle photodiode and IR LED on the stator, but use narrow-angle components on the rotor. The two rx/tx pairs are -arranged next to the motor on opposite sides. By placing the narrow-angle rotor rx/tx components on the outside as -shown in Figure \ref{ir_tx_schema}, the motor shields both IR links from crosstalk. The rotor transmitter LED is -driven at $\SI{1}{\milli\ampere}$ while the stator transmitter LED is driven at $\SI{20}{\milli\ampere}$. - -\begin{figure} - \center - \includegraphics{ir_tx_schema.pdf} - \caption{Schema of our bidirectional IR communication link between rotor and stator, view along axis of rotation. 1 - - Rotor base PCB. 2 - Stator IR link PCB. 3 - Motor. 4 - receiver PIN photodiode. 5 - transmitter IR LED.} - \label{ir_tx_schema} -\end{figure} +\subsection{Power transmission through the rotating joint} + +The spinning mesh has its own autonomous monitoring circuit. This spinning monitoring circuit needs both power and data +connectivity to the stator. At the monitoring circuit's low power consumption (see +Appendix~\ref{sec_energy_calculations}), power transfer efficiency is irrelevant so we decided against mechanically +complex solutions such as slip rings or electronically complex ones such as inductive power transfer. Instead we opted +to use six series-connected solar cells mounted on the end of our cylindrical rotor that are directly fed into a large +$\SI{33}{\micro\farad}$ ceramic buffer capacitor. This solution provides around $\SI{3.0}{\volt}$ at several tens of +$\si{\milli\ampere}$ to the payload when illumination using either a $\SI{60}{\watt}$ incandescent light bulb or a +flicker-free LED studio light of similar brightness\footnote{LED lights intended for room lighting exhibit significant +flicker that can cause the monitoring circuit to reset. Incandescent lighting requires some care in shielding the IR +jata link from interference.}. + +\subsection{Data transmission through the rotating joint} + +Besides power transfer from stator to rotor we need a reliable, bidirectional data link to transmit mesh status and a +low-latency heartbeat signal. We chose to transport an $\SI{115}{\kilo\baud}$ UART signal through a simple IR link for a +quick and robust solution. The link's transmitter directly drives a standard narrow viewing angle IR led through a +transistor. The receiver has an IR PIN photodiode reverse-biased at $\frac{1}{2}V_\text{CC}$ feeding into a an +\texttt{MCP6494} general purpose opamp configured as an $\SI{100}{\kilo\ohm}$ transimpedance amplifier. As shown in +Figure \ref{photolink_schematic}, the output of this TIA is amplified one more time, before being squared up by a +comparator. Our design trades off stator-side power consumption for a reduction in rotor-side power consumption by +using a narrow-angle IR led and photodiode on the rotor, and wide-angle components at a higher LED current on the +stator. Figure~\ref{ir_tx_schema} shows the physical arrangement of both links. The links face opposite one another and +are shielded by the motor's body in the center of the PCB. + +% We used an \texttt{MCP6494} quad CMOS op-amp. At a specified $\SI{2}{\milli\ampere}$ current +% consumption it is within our rotor's power budget, and its Gain Bandwidth Product of $\SI{7.5}{\mega\hertz}$ yields a +% useful transimpedance in the photodiode-facing TIA stage. \begin{figure} - \center - \includegraphics[width=9cm]{photolink_schematic.pdf} - \caption{Schematic of the IR communication link. Component values are only examples. In particular C2 depends highly - on the photodiode used and stray capacitances due to the component layout.} - \label{photolink_schematic} + \begin{subfigure}{0.3\textwidth} + \includegraphics[width=4.5cm]{ir_tx_schema.pdf} + \caption{Basic layout, view along axis of rotation. 1 + - Rotor base PCB. 2 - Stator IR link PCB. 3 - Motor. 4 - receiver PIN photodiode. 5 - transmitter IR LED.} + \label{ir_tx_schema} + \end{subfigure} + \hfill + \begin{subfigure}{0.65\textwidth} + \includegraphics[width=9cm]{photolink_schematic.pdf} + \caption{Schematic with sample component values. C2 is highly dependent on the photodiode characteristics and + stray capacitances.} + \label{photolink_schematic} + \end{subfigure} + \caption{IR data link implementation} \end{figure} -\subsection{Power transmission through rotating joint} - -Besides the data link, the other electrical interface we need between rotor and stator is for power transmission. We -power Since this prototype serves only demonstration purposes, we chose to use the simplest possible method of power -transmission: solar cells. We mounted six series-connected solar cells in three commercially available modules on the -circular PCB at the end of our cylindrical rotor. The solar cells direclty feed the rotor's logic supply with buffering -by a large $\SI{33}{\micro\farad}$ ceramic capacitor. With six cells in series, they provide around $\SI{3.0}{\volt}$ at -several tens of $\si{\milli\ampere}$ given sufficient illumination. - -For simplicity and weight reduction, at this point we chose to forego large buffer capacitors on the rotor. This means -variations in solar cell illumination directly couple into the microcontroller's supply rail. Initially, we experimented -with regular residential LED light bulbs, but those turned out to have too much flicker and lead to our microcontroller -frequently rebooting. Trials using an incandecent light produced a stable supply, but the large amount of infrared light -emitted by the incandecent light bulb severely disturbed our near-infrared communication link. As a consequence of -this, we settled on a small LED light intended for use as a studio light that provdided us with almost flicker-free -light at lower frequencies, leading to a sufficiently stable microcontroller VCC rail without any disturbance to the IR -link. +%%% FIXME rework parts below \subsection{Evaluation} +% FIXME maybe move this to last chapter (conclusion)? to be in line with new mems evaluation chapter? After building our prototype inertial HSM according to the design decisions we outlined above, we performed a series of experiments to validate the critical components of the design. @@ -586,6 +554,93 @@ HSM concept practical. \label{prototype_early_comms} \end{figure} +% FIXME rework parts above +% new section follows. + +\section{Using MEMS accelerometers for braking detection} + +Using the prototype from the previous section, we performed an evaluation of an \partnum{AIS 1120} commercial automotive +MEMS accelerometer as a braking sensor. The device is mounted inside our prototype at a radius of +$\SI{55}{\milli\meter}$ from the axis of rotation to the center of the device's package. The \partnum{AIS 1120} provides +a measurement range of $\pm 120\,g$. At its 14-bit resolution, one LSB corresponds to $15\,\mathrm{m}g$. + +Our prototype IHSM uses a motor controller intended for use in RC quadcopters. In our experimental setup, we manually +control this motor controller through an RC servo tester. We measure the devices rotation speed using a magnet fixed to +the rotor and a reed switch held closeby by an articulating arm. The reed switch output is digitized using an USB logic +analyzer at a sampling rate of $\SI{100}{\mega\hertz}$. We calculcate rotation frequency as a $\SI{1}{\second}$ running +average over debounced interval lengths of this captured signal. + +The accelerometer is controlled from the \partnum{STM32} microcontroller on the rotor of our IHSM prototype platform. +Timed by an external quartz, the microcontroller samples accelerometer readings at $\SI{10}{\hertz}$. Readings are +accumulated in a small memory buffer, which is continuously transmitted out through the prototype platform's infrared +link. Data is packetized with a sequence number indicating the buffer's position in the data stream and a CRC-32 +checksum for error detection. On the host, a Python script stores all packets received with a valid checksum in an +SQLite database. + +Data analysis is done separately from data capture. An analysis IPython Notebook reads captured packets and reassembles +the continuous sample stream based on the packets' sequence numbers. The low $\SI{10}{\hertz}$ sampling rate and high +$\SI{115}{\kilo Bd}$ transmission speed lead to a large degree of redundancy with gaps in the data stream being rare. +This allowed us to avoid writing retransmission logic or data interpolation. + +Figure~\ref{fig-acc-steps} shows an entire run of the experiment. During this run, we started with the rotor at +standstill, then manually increased its speed of rotation in steps. Areas shaded gray are intervals where we manually +adjust the rotors speed. The unshaded areas in between are intervals when the rotor speed is steady. +Figure~\ref{fig-acc-stacked} shows a magnified view of these periods of steady rotor speed. In both graphs, orange +lines indicate centrifugal acceleration as calculated from rotor speed measurements. Visually, we can see that +measurements and theory closely match. Our frequency measurements are accurate and the main source of error are the +accelerometer's intrinsic errors as well as error in its placement due to construction tolerances. + +The accelerometer's primary intrinsic errors are offset error and scale error. Offset error is a fixed additive offset +to all measurements. Scale error is an error proportional to a measurements value that results from a deviation between +the device's specified and actual sensitivity. We correct for both errors by first extracting all stable intervals from +the time series, then fitting a linear function to the measured data. Offset error is this linear function's intercept, +and scale error is its slope. We then apply this correction to all captured data before plotting and later analysis. +Despite its simplicity, this approach already leads to a good match of measurements and theory modulo a small part of +the device's offset remaining. At high speeds of rotation this remaining offset does not have an appreciable impact, but +due to the quadratic nature of centrifugal acceleration at low speeds it causes a large relative error of up to +$\SI{10}{\percent}$ (at $\SI{95}{rpm}$). + +After offset and scale correction, we applied a low-pass filter to our data. The graphs show both raw and filtered data. +Raw data contains significant harmonic content. This content is due to vibrations in our prototype. FFT analysis shows +that this harmonic content is a clean intermodulation product of the accelerometers sampling rate and the speed of +rotation with no other visible artifacts. + +Figure~\ref{fig-acc-theory} shows a plot of our measurement results against frequency. Data points are shown in dark +blue, and theoretical behavior is shown in orange. + +\begin{figure} + \center + \includegraphics[width=0.7\textwidth]{../../prototype/sensor-analysis/fig-acc-theory-meas-run50.pdf} + \caption{Centrifugal acceleration versus angular frequency in theory and in our experiments. Experimental + measurements are shown after correction for device-specific offset and scale error. As is evident, our measurements + agree very well with our theoretical results. Above \SI{300}{rpm}, the relative acceleration error was consistently + below $\SI{0.5}{\percent}$. Below $\SI{300}{rpm}$, residual offset error remaining after our first-order corrections + has a strong impact ($0.05\,g$ absolute or $8\%$ relative at $\SI{95}{rpm}$.} + \label{fig-acc-theory} +\end{figure} +% FIXME note how to sense actual rotation frequency somewhere -> falls out of motor driver + +\begin{figure} + \begin{subfigure}{0.5\textwidth} + \center + \includegraphics[width=1.1\textwidth]{../../prototype/sensor-analysis/fig-acc-trace-steps-run50.pdf} + \caption{Raw recording of accelerometer measurements during one experiment run. Shaded areas indicate time + intervals when we manually adjusted speed, leading to invalid measurements.} + \label{fig-acc-steps} + \end{subfigure} + \hfill + \begin{subfigure}{0.45\textwidth} + \center + \includegraphics[width=1.1\textwidth]{../../prototype/sensor-analysis/fig-acc-trace-stacked-run50.pdf} + \caption{Valid measurements cropped out from \ref{fig-acc-steps} for various frequencies. Intermodulation + artifacts from the accelerometer's $\SI{10}{\hertz}$ sampling frequency and the $\SIrange{3}{18}{\hertz}$ + rotation frequency due to device vibration are clearly visible.} + \label{fig-acc-stacked} + \end{subfigure} + \label{fig-acc-traces} + \caption{Traces of acceleration measurements during one experiment run.} +\end{figure} + \section{Conclusion} \label{sec_conclusion} To conclude, in this paper we introduced inertial hardware security modules (iHSMs), a @@ -685,15 +740,6 @@ or commercial restrictions. Where possible, we ask you to cite this paper and at authors. \center{ - \center{\ccbysa} - - \center{This work is licensed under a Creative-Commons ``Attribution-ShareAlike 4.0 International'' license. The - full text of the license can be found at:} - - \center{\url{https://creativecommons.org/licenses/by-sa/4.0/}} - - \center{For alternative licensing options, source files, questions or comments please contact the authors.} - \center{This is version \texttt{\input{version.tex}\unskip} generated on \today. The git repository can be found at:} \center{\url{https://git.jaseg.de/rotohsm.git}} diff --git a/doc/paper/rotohsm_tech_report.pdf b/doc/paper/rotohsm_tech_report.pdf index aae2445..4f39c19 100644 Binary files a/doc/paper/rotohsm_tech_report.pdf and b/doc/paper/rotohsm_tech_report.pdf differ -- cgit