科学文献
科技文献的定义

科技文献的定义科技文献是指记录科学研究成果、科技发展动态和科技管理经验的文献资料。
它是科学研究、技术创新和科技管理的重要依据和参考,对于推动科技进步和社会发展具有重要的作用。
科技文献的主要特点是准确性、权威性和时效性。
作为科学研究成果的记录,科技文献要求准确地反映研究方法、实验数据和结论,确保信息的真实性和可靠性。
同时,科技文献也需要具备权威性,即来源于有专业知识和经验的科学家、工程师和技术专家,经过同行评议和学术机构认可的论文、报告和专著等。
此外,科技文献还要具备时效性,及时反映科技发展的最新成果和动态,使读者能够及时了解科技前沿和最新趋势。
科技文献主要包括学术论文、科技报告、专利文献、技术标准和科技期刊等。
学术论文是科学研究成果的主要表现形式,它通过系统的实验或理论分析,提出新的理论、方法和结论,通过同行评议后发表在学术期刊上。
科技报告是研究项目的成果报告或研究机构的研究成果总结,它通常包含研究目的、方法、实验结果和结论等内容。
专利文献是专利申请和授权的文件,记录了发明创造的具体技术方案和实施方式。
技术标准是科技发展的规范和指南,通过规定产品的技术要求和测试方法,保障产品的质量和安全。
科技期刊是科学研究成果的重要发布渠道,它定期出版学术论文和研究报告,提供科技信息的交流和共享平台。
科技文献的利用可以促进科学研究的发展和技术创新的进步。
科学家和工程师可以通过查阅和分析科技文献,了解前人的研究成果和经验,避免重复劳动和错误,为自己的研究工作奠定基础。
科技管理人员可以通过研究科技文献,掌握科技发展的动态和趋势,制定科技政策和计划,引导科技创新和产业升级。
工程师和技术人员可以通过科技文献,学习新的技术方法和应用案例,提高自己的专业能力和技术水平。
科技文献是科学研究、技术创新和科技管理的重要资源和工具。
科技工作者应该重视科技文献的收集和利用,不断更新自己的知识和技能,推动科技进步和社会发展。
同时,科技出版机构和科技管理部门也应该加强对科技文献的管理和服务,提高科技文献的质量和影响力,为科技创新提供有力支持。
高中生如何有效阅读科学文献

高中生如何有效阅读科学文献科学文献是高中生学习科学知识的重要资源,它们包含了前沿的研究成果和学术观点。
然而,对于许多高中生来说,阅读科学文献可能是一项具有挑战性的任务。
本文将介绍一些帮助高中生有效阅读科学文献的方法和技巧。
一、选择适合的文献在开始阅读科学文献之前,高中生应该学会选择适合自己的文献。
首先,他们可以通过在学校图书馆或在线数据库中搜索关键词来找到相关的文献。
其次,他们应该根据自己的学习目标和兴趣选择文献。
例如,如果他们对生物学感兴趣,那么可以选择与生物学相关的研究论文。
二、了解文献的结构科学文献通常由摘要、引言、方法、结果和讨论等部分组成。
高中生在阅读文献之前,应该先了解这些部分的作用和内容。
摘要通常是文献的概要,可以帮助读者快速了解研究的目的和主要结果。
引言部分介绍了研究的背景和目的,方法部分描述了研究的实验设计和数据采集方法,结果部分展示了实验结果,讨论部分对结果进行解释和分析。
三、注意关键词和术语科学文献中常常使用一些专业的术语和关键词,高中生应该学会识别和理解这些术语。
他们可以通过查阅词典或在线资源来解释这些术语的含义。
此外,高中生还可以将这些术语和关键词记录下来,以便在阅读过程中进行参考和复习。
四、提问和思考在阅读科学文献时,高中生应该保持积极的思考和提问的态度。
他们可以思考文献中的研究问题、实验设计和结果,并提出自己的疑问和观点。
通过提问和思考,他们可以更好地理解文献的内容,并培养批判性思维能力。
五、扩展阅读阅读科学文献不仅限于一篇文章,高中生可以通过扩展阅读来深入了解某个主题。
例如,他们可以查阅相关的综述文章、书籍或其他研究论文,以获取更全面的知识。
扩展阅读还可以帮助高中生了解当前研究领域的热点问题和最新进展。
六、记录和总结在阅读科学文献时,高中生应该养成记录和总结的习惯。
他们可以使用笔记本或电子工具来记录重要的观点、关键词和疑问。
此外,他们还可以将阅读的内容进行总结和归纳,以便后续的学习和复习。
如何阅读科学文献

如何阅读科学文献阅读科学文献对于科研工作者和学术界的人士非常重要。
通过阅读科学文献,我们可以了解最新的研究进展,与同行进行交流与合作,提高自身的学术能力和水平。
然而,对于一些初学者或者对特定领域不熟悉的人来说,阅读科学文献可能是一项具有挑战性的任务。
在本文中,我将分享一些关于如何阅读科学文献的方法和技巧。
一、了解文献的分类和来源科学文献通常可以分为多种类型,包括期刊论文、会议论文、学位论文、专著和技术报告等。
这些文献来源的权威性和可信度有所不同,应根据需要选择合适的文献进行阅读。
常见的文献数据库包括PubMed、Scopus、Web of Science等,可以通过检索关键词或者作者的姓名来查找相关的文献。
二、阅读文献之前的准备工作在阅读科学文献之前,我们可以进行一些准备工作,以提高阅读效率和理解能力。
首先,要了解相关领域的基本知识和术语,这样在阅读文献时就能更好地理解和理解作者的观点和实验内容。
其次,可以查找文献的综述或者评论性文章,了解该领域的发展和当前的研究进展,从而对文献有一个整体的了解。
最后,可以制定一个阅读计划,设定合理的阅读时间和目标,提高阅读的效率。
三、阅读科学文献的技巧1. 精读和泛读结合对于篇幅较长或者对自己比较重要的文献,可以进行精读。
在精读时,要认真阅读摘要和介绍部分,了解研究的背景和目的,然后逐段、逐句进行仔细阅读,理解作者的实验设计和研究结果。
在阅读过程中,可以做一些标记或者写下关键点,以便于后续的回顾和整理。
对于篇幅较长或者对自己不是很重要的文献,可以进行泛读。
在泛读时,可以关注文献的结构、图表和重点段落,了解作者的主要观点和研究结果。
泛读可以帮助快速获取信息,筛选出对自己研究有用的文献。
2. 多角度阅读在阅读科学文献时,要注意从多个角度进行思考和分析。
可以思考文献的创新点、实验设计、结果解释以及与其他相关文献的联系。
可以尝试用自己的话总结和表达作者的观点和结论,以帮助更好地理解文献内容。
科学文献的名词解释

科学文献的名词解释
文献:
1. Abstract
2. Bibliographic Database
3. Editor
4. Index
一、Abstract:
抽象是科学文献中概述性段落的内容,即文章的摘要,它在文献的开头,能简要介绍文献的内容和目的,是科学文献查找、分析和利用的重要基础。
Abstract由一般性问题、技术方法、重要结果、结论和指出事实的综述性的评论组成,概述文献的内容及方法,是检索文献信息的重要依据。
二、Bibliographic Database:
文献数据库是以文献数据为基础建立起来的文献信息体系,其主要内容是存储文献信息(如书籍、期刊、报纸、图书、报告摘要、摘录、贴文等)的元数据,并提供跨文献的快速检索的功能。
一般而言,文献数据库由代表文献的描述性元数据(如题名、作者、出版社、出版日期等)和用于检索所建立的全文索引组成。
三、Editor:
编辑是指组织、审查和整理文献内容,以便发表的这类编辑服务活动。
编辑可以编排、修改、撰写、组织文献,编辑从文献撰写、组织和修订等方面起着协调作用,以确保出版物的质量。
四、Index:
索引是科学文献检索的一个重要技术工具,它的主要目的是使读者能够轻松找到所需要的信息。
索引包括有关文献的词汇表,能够提供有用的参考资料,而无需检查整个文献的文本内容。
另外,索引还可以帮助读者了解文献的整体框架,有利于从文献中快速获取信息。
十大科技文献源

十大科技文献源科技的发展日新月异,不断推动着人类社会的进步。
以下是十大科技文献源,它们记录了人类在不同领域的探索和创新。
1.《自然》(Nature)作为世界上最古老的科学杂志之一,《自然》杂志为读者提供了丰富的科学研究成果和前沿的科技进展。
它既包括基础科学领域的研究,也关注应用科学的发展。
2.《科学》(Science)《科学》杂志是世界上最有影响力的综合性科学杂志之一,涵盖了各个学科领域的最新研究成果。
它以其高质量的科学报道和严谨的学术评审而闻名,是科学界的权威之一。
3.《人工智能》(Artificial Intelligence)《人工智能》期刊聚焦于人工智能领域的研究和应用,包括机器学习、自然语言处理、计算机视觉等。
它发布的论文对于推动人工智能技术的发展具有重要意义。
4.《物理评论快报》(Physical Review Letters)《物理评论快报》是物理学领域最具影响力的学术期刊之一,发表了许多重要的物理学突破性研究。
它以其简洁、精确和具有启发性的论文而受到广泛关注。
5.《细胞》(Cell)《细胞》杂志是细胞生物学和分子生物学领域的顶级期刊之一,报道了该领域的最新研究成果和突破性发现。
它对于理解生命的基本机制和疾病的发生机理具有重要意义。
6.《计算机视觉国际会议》(Conference on Computer Vision and Pattern Recognition)计算机视觉是人工智能领域的一个重要分支,该会议是该领域最重要的学术会议之一。
它汇集了来自全球的顶尖研究人员,分享了最新的计算机视觉技术和应用。
7.《美国国家科学院院刊》(Proceedings of the National Academy of Sciences)《美国国家科学院院刊》是美国国家科学院的官方期刊,发表了各个学科领域的重要研究成果。
它是一本跨学科的期刊,涵盖了自然科学、社会科学和工程技术等领域。
8.《医学》(The Lancet)《医学》杂志是世界上最具影响力的医学期刊之一,发表了许多重要的医学研究。
科学阅读的方法和技巧

科学阅读的方法和技巧一、选择合适的文献1. 学术期刊:选择相关领域的学术期刊,如《Nature》、《Science》等,这些期刊发布的论文通常是经过同行评议且质量较高的。
2. 学术数据库:如Google学术、PubMed等,可以通过关键词检索相关文献。
3.学术会议:参考学术会议的论文集,了解最新的研究进展。
4.专业书籍:选择有权威性的专业书籍,如教科书、专著等。
二、调整阅读策略科学文献通常包含大量的专业术语和公式,阅读起来较为困难。
为了更好地理解文献内容,可以采用以下阅读策略:1.预览:先浏览全文的标题、摘要和关键词,了解文献的大致内容和观点。
2.筛选:根据自己的兴趣和研究方向,选择有重要参考价值的章节或段落进行重点阅读。
3.聚焦:在阅读过程中,将注意力聚焦在关键词、论证主线和实验结果等重要内容上。
4.意识流:尽量保持集中的阅读时间,避免受到干扰和分散注意力。
5.笔记:在阅读过程中做好笔记,记录关键信息和自己的理解和思考。
三、理解文献内容科学文献通常采用科学语言和专业术语,为了更好地理解文献内容,可以采用以下方法:1.查阅词典和参考书:查阅相关课本、词典、参考书籍等,弄清楚不熟悉的术语和概念。
2.加深背景知识:扩大自己的科学背景知识,了解相关领域的基本原理和理论框架。
3.多角度理解:通过阅读多个文献,了解不同研究观点和方法,从不同角度思考和分析问题。
4.精确解释:将复杂的概念或内容用自己的语言重新解释一遍,以确保自己理解透彻。
四、分析论证逻辑科学文献通常有一定的逻辑结构,分析论证逻辑有助于深入理解文献内容。
可以采用以下方法:1.总结主旨:通过阅读摘要、引言和结论等部分,总结文献的主旨和观点。
4.反思批判:对文献的内容进行批判性思考,发现可能存在的问题和不足之处。
五、扩展思考和应用1.感知科学思维:思考作者是如何发现问题、提出假设、设计实验和得出结论的,借鉴科学思维方法。
2.拓展思考:将文献中的观点与自己的观点进行比较和对比,思考存在的差异和原因,并以此为基础进行拓展思考。
科学文献阅读技巧详解

科学文献阅读技巧详解科学文献阅读技巧详解在科学研究的道路上,掌握有效的文献阅读技巧至关重要。
想象一下,文献就像是一座座深奥的宝库,里面珍藏着无数宝贵的知识和经验。
然而,要想从这些宝库中获取有用的信息,需要具备一定的技巧和策略。
首先,当你面对一篇新的科学文献时,它可能会显得有些“冷漠”。
不过,不要担心,这只是因为它还没有“认识”你。
开始阅读前,先浏览摘要部分,这就像与文献“打个招呼”,让它知道你对它感兴趣。
接下来,进入文献的正文部分,你会发现它有如一位导游,带领你探索未知的领域。
要有耐心,不要急于求成。
有时候,文献会使用复杂的术语和句子,就像在说一门外语一样。
这时,不妨反复阅读,逐步理解每一个词语背后的含义,就像与文献进行一场深入的交流。
在阅读过程中,可以时常停下来思考,并做好记录。
文献常常会提出问题或者让你有新的启发,这就像它在与你进行互动,促使你深入思考。
记得,做好笔记非常重要,这有助于你将碎片化的信息整理成有条理的知识体系。
此外,不要忽视文献中的图表和数据。
它们就像文献的“视觉演示”,通过直观的方式展示研究结果。
深入理解图表背后的数据,有助于你更全面地把握文献的核心内容。
最后,要保持批判性思维。
就像与一位智者交谈一样,不要轻易接受文献中的每一个观点。
要学会提出问题,评估实验设计的有效性,并思考研究结果的可能局限性。
这样,你才能更好地理解文献,甚至为未来的研究提供新的思路和方法。
总结来说,科学文献阅读并非一项简单的任务,它需要技巧和耐心。
通过与文献建立良好的互动关系,你将能够开启一段充满发现和启发的学术之旅。
不断地练习和改进阅读技巧,相信你定能在科学研究的道路上越走越远。
中国科学引用文献格式

中国科学(Science China)的引用文献格式通常遵循国际通用的科技文献引用规范,以下是一种常见的引用格式:
期刊文章:
作者. 文章标题. 刊名, 年份, 卷号(期号): 起始页码-结束页码.
例如:
王明, 李华, 赵丽. 量子通信的新进展. 科学通报, 2021, 66(12): 1234-1256.
书籍:
作者. 书名. 版本(初版可省略). 出版地: 出版社, 出版年份.
例如:
张三. 物理学导论. 第3版. 北京: 高等教育出版社, 2018.
学位论文:
作者. 论文标题. 学位级别. 授予单位, 年份.
例如:
李四. 量子计算的研究. 博士学位论文. 清华大学, 2022.
请注意,具体的引用格式可能会根据期刊或出版机构的要求有所不同,因此在撰写论文时应参照目标期刊或出版社的投稿指南进行调整。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Trading-OffType-Inference Memory ComplexityAgainst CommunicationKonstantin Hypp¨o nen1,David Naccache2,Elena Trichina1,and AlexeiTchoulkine21University of KuopioDepartment of Computer SciencePo.B.1627,FIN-70211,Kuopio,Finland{konstantin.hypponen,elena.trichina}@u.fi2Gemplus Card InternationalApplied Research&Security Centre34rue Guynemer,Issy-les-Moulineaux,92447,France{david.naccache,alexei.tchoulkine}@Abstract.While bringing considerableflexibility and extending thehorizons of mobile computing,mobile code raises major security issues.Hence,mobile code,such as Java applets,needs to be analyzed before ex-ecution.The byte-code verifier checks low-level security properties thatensure that the downloaded code cannot bypass the virtual machine’s se-curity mechanisms.One of the statically ensured properties is type safety.The type-inference phase is the overwhelming resource-consuming partof the verification process.This paper addresses the RAM bottleneck met while verifying mobilecode in memory-constrained environments such as smart-cards.We pro-pose to modify classic type-inference in a way that significantly reducesthe memory consumption in the memory-constrained device at the detri-ment of its distrusted memory-rich environment.The outline of our idea is the following,throughout execution,the mem-ory frames used by the verifier are MAC-ed and exported to the terminaland then retrieved upon request.Hence a distrusted memory-rich ter-minal can be safely used for convincing the embedded device that thedownloaded code is secure.The proposed protocol was implemented on JCOP20and JCOP30Javacards using IBM’s JCOP development tool.1IntroductionThe Java Card architecture for smart cards[1]allows new applications,called applets,to be downloaded into smart cards.While general security issues raised by applet download are well known[9],transferring Java’s safety model into resource-constrained devices such as smart cards appears to require the devising of delicate security-performance trade-offs.When a Java class comes from a distrusted source,there are two basic man-ners to ensure that no harm will be done by running it.Thefirst is to interpret the code defensively[2].A defensive interpreter is a virtual machine with built-in dynamic runtime verification capabilities.De-fensive interpreters have the advantage of being able to run standard classfiles resulting from any Java compilation chain but appear to be slow:the security tests performed during interpretation slow-down each and every execution of the downloaded code.This renders defensive interpreters unattractive for smart cards where resources are severely constrained and where,in general,applets are downloaded rarely and run frequently.Another method consists in running the newly downloaded code in a com-pletely protected environment(sandbox),thereby ensuring that even hostile code will remain harmless.In this model,applets are not compiled to machine lan-guage,but rather to a virtual-machine assembly-language called byte-code.Upon download,the applet’s byte-code is subject to a static analysis called byte-code verification which purpose is to make sure that the applet’s code is well-typed.This is necessary to ascertain that the code will not attempt to violate Java’s security policy by performing ill-typed operations at runtime(e.g.forging object references from integers or calling directly API private methods).Today’s de facto verification standard is Sun’s algorithm[7]which has the advantage of being able to verify any classfile resulting from any standard compilation chain.While the time and space complexities of Sun’s algorithm suit personal computers,the memory complexity of this algorithm appears prohibitive for smart cards,where RAM is a significant cost-factor.This limitation gave birth to a number of innovating workarounds:Leroy[5,6]devised a verification scheme which memory complexity equals the amount of RAM necessary to run the verified applet.Leroy’s solution relies on off-card code transformations whose purpose is to facilitate on-card verification by eliminating the memory-consumingfix-point calculations of Sun’s original algorithm.Proof carrying code[11](PCC)is a technique by which a side product of the full verification,namely,thefinal type information inferred at the end of the verification process(fix-point),is sent along with the byte-code to allow a straight-line verification of the applet.This extra information causes some trans-mission overhead,but the memory needed to verify a code becomes essentially equal to the RAM necessary to run it.A PCC off-card proof-generator is a rather complex software.Various other ad-hoc memory-optimization techniques exist as well[10,8].Our results:The work reported in this paper describes an alternative byte-code verification solution.Denoting by M max the number of variables claimed by the verified method and by J the number of jump targets in it,we show how to securely distribute the verification procedure between the card and the terminal so as to reduce the card’s memory requirements from O(M max J)to O(J log J+cM max)where c is a small language-dependent constant or,when a higher communication burden is tolerable,to a theoretic O(log J+cM max).The rest of the paper is organized as follows:the next section recalls Java’s security model and Sun’s verification algorithm with a specific focus on its data-flow analysis part.The subsequent sections describe the new verification proto-col,which implementation details are given in the last section.2Java SecurityThe Java Virtual Machine(JVM)Specification[7]defines the executablefile structure,called the classfile format,to which all Java programs are compiled. In a classfile,the executable code of methods(Java methods are the equivalent of C functions)is found in code-array structures.The executable code and some method-specific runtime information(namely,the maximal operand stack size S max and the number of local variables L max claimed by the method3)constitute a code-attribute.We briefly overview the general stages that a Java code goes through upon download.To begin with,the classes of a Java program are translated into independent classfiles at compile-time.Upon a load request,a classfile is transferred over the network to its recipient where,at link-time,symbolic references are resolved. Finally,upon method invocation,the relevant method code is interpreted(run) by the JVM.Java’s security model is enforced by the class loader restricting what can be loaded,the classfile verifier guaranteeing the safety of the loaded code and the security manager and access controller restricting library methods calls so as to comply with the security policy.Class loading and security management are essentially an association of lookup tables and digital signatures and hence do not pose particular implementation problems.Byte-code verification,on which we focus this paper,aims at predicting the runtime behavior of a method precisely enough to guarantee its safety without actually having to run it.2.1Byte-Code VerificationByte-code verification[4]is a link-time phase where the method’s run-time be-havior is proved to be semantically correct.The byte-code is the executable sequence of bytes of the code-array of a method’s code-attribute.The byte-code verifier processes units of method-code stored as classfile attributes.An initial byte-code verification pass breaks the byte sequence into successive instructions,recording the offset(program point) of each instruction.Some static constraints are checked to ensure that the byte-code sequence can be interpreted as a valid sequence of instructions taking the right number of arguments.As this ends normally,the receiver assumes that the analyzedfile complies with the general syntactical description of the classfile format.Then,a second verification step ascertains that the code will only manipulate values which types are compatible with Java’s safety rules.This is achieved by a type-based data-flow analysis which abstractly executes the method’s byte-code, 3M max=L max+S max.by modelling the effect of the successive byte-codes on the types of the variables read or written by the code.The next section explains the semantics of type checking,i.e.,the process of verifying that a given pre-constructed type is correct with respect to a given classfile.We explain why and how such a type can always be constructed and describe the basic idea behind data-flow analysis.The Semantics of Type Checking A natural way to analyze the behavior of a program is to study its effect on the machine’s memory.At runtime,each program point can be looked upon as a memory instruction frame describing the set of all the runtime values possibly taken by the JVM’s stack and local variables.Since run-time information,such as actual input data is unknown before execution starts,the best an analysis may do is reason about sets of possible computations.An essential notion used for doing so is the collecting semantics defined in[3]where,instead of computing on a full semantic domain(values), one computes on a restricted abstract domain(types).↑stack growth 12711@346127.551113=valuesintLjava/lang/String;FHFLint=typesFor reasoning with types,one must precisely classify the information ex-pressed by types.A natural way to determine how(in)comparable types are is to rank all types in a lattice L.A brief look at the toy lattice depicted below suffices tofind-out that animal is more general than fly,that int and spider are not comparable and that cat is a specific animal.Hence,knowing that a variable is designed to safely contain an animal,one can infer that no harm can occur if during execution this variable would successively contain a cat,a fly and an insect.However,should the opposite be detected(e.g.an instruction would attempt to use a variable supposed to contain an animal as if it were a cat)the program should be rejected as unsafe.The most general type is called top and denoted⊤.⊤represents the potential simultaneous presence of all types,i.e.the absence of(specific)information.By definition,a special null-pointer type(denoted null)terminates the inheritance chain of all object descendants.Formally,this defines a pointed complete partial order(CPO) on the lattice L.⊤ւցint Object↓animalւցcat insect↓ւ↓ցnull spider bee fly↓↓↓null null nullStack elements and local variable types are hence tuples of elements of L to which one can apply point-wise ordering.L=⊤ւ↓ցint···Objectւ↓ցτ1···τkւ↓ցւ↓ց...···......···...τ···τ···τ···τ···↓↓↓↓↓↓null null null null null nullAbstract Interpretation The verification process described in[7]§4.9,is an (iterative data-flow analysis)algorithm that attempts to build an abstract de-scription of the JVM’s memory for each program point.A byte-code is safe if the construction of such an abstract description succeeds.Assume,for example,that an iadd is present at some program point.The i in iadd hints that this instruction operates on integers.iadd’s effect on the JVM is indeed very simple:the two topmost stack elements are popped,added and the sum is pushed back into the stack.An abstract interpreter will disregard the arithmetic meaning of iadd and reason with types:iadd pops two int elements from the stack and pushes back an int.From an abstract perspective,iadd and isub have identical effects on the JVM.As an immediate corollary,a valid stack for executing an iadd must have a value which can be abstracted as int.int.S,where S may contain any sequence of types(which are irrelevant for the interpretation of our iadd).After executing iadd the stack becomes int.SDenoting by L the JVM’s local variable area(irrelevant to iadd),the total effect of iadd’s abstract interpretation on the JVM’s memory can be described by the transition ruleΦ:iadd:(int.int.S,L)→(int.S,L)The following table defines the transition rules of seven representative JVM instructions4.4Note that the test n∈L is equivalent to ascertaining that0≤n≤L max.Instruction Transition ruleΦSecurity testiconst[n](S,L)→(int.S,L)|S|<S maxiload[n](S,L)→(int.S,L)n∈L,L[n]==int,|S|<S maxistore[n](int.S,L)→(S,L{n→int})n∈Laload[n](S,L)→(L[n].S,L)n∈L,L[n] Object,|S|<S max astore[n](τ.S,L)→(S,L{n→τ})n∈L,τ Objectdup(τ.S,L)→(τ.τ.S,L)|S|<S maxgetfield C.f.τ(ref(D).S,L)→(τ.S,L)D CFor thefirst instruction of the method,the local variables that represent parameters are initialized with the typesτj indicated by the method’s signature; the stack is empty(ǫ)and all other local variables arefilled with⊤s.Hence,the initial frame is set to:(ǫ,(this,τ1,...,τn−1,⊤,...,⊤))For other instructions,no information regarding the stack or the local variables is available.Verifying a method whose body is a straight-line code(no branches),is easy: we simply iterate the abstract interpreter’transition functionΦover the succes-sive instructions,taking the stack and register types after any given instruction as the stack and register types before the next instruction.The types describing the successive JVM memory-states produced by the successive instructions are called working frames.Denoting by in(i)the frame before instruction i and by out(i)the frame after instruction i,we get the following data-flow equation where evaluation starts from the right:in(i+1)←out(i)←Φi(in(i))Branches introduce forks and joins into the method’sflowchart.Let us illus-trate these with the following example:program point Java codeint m(int q){p1֒→int x;int y;if(q==0)p2֒→{x=1;...}p3֒→else{y=2;...}p4֒→...}After program point p1one can infer that variable q has type int.This is denoted as out(p1)={q=int,x=⊤,y=⊤}.After the if’s then branch,we infer the type of variable x,i.e.,out(p2)={q=int,x=int,y=⊤}.After the else,we learn that out(p3)={q=int,x=⊤,y=int}.However,at p4,nothing can be said about neither x nor y.We hence pru-dently assume that in(p4)={q=int,x=⊤,y=⊤}by virtue of the principlethat if two execution paths yield different types for a given variable,only the lesser-information type can serve for further calculations.In other words,we assume the worst and check that,still,type-violations will not occur.Thus,if an instruction i has several predecessors with different exit frames,i’s frame is computed as the least common ancestor5(LCA)of all the predecessors’exit frames:in(i)=LCA{out(i)|j∈Predecessor(i)}.In our example:in(p4)={q=int,x=⊤=LCA(int,⊤),y=⊤= LCA(⊤,int)}.Finding an assignment of frames to program points which is sufficiently con-servative for all execution paths requires testing them all;this is what the ver-ification algorithm does.Whenever some in(i)is adjusted,all frames in(j)that depend on in(i)have to be adjusted too,causing additional iterations until a fix-point is reached(i.e.,no more adjustments are required).Thefinal set of frames is a proof that the verification terminated with success.In other words, that the byte-code is well-typed.2.2Sun’s Type-Inference AlgorithmThe algorithm below which summarizes the verification process,is taken from [7].The treatment of exceptions(straightforward)is purposely omitted for the sake of clarity.The initialization phase of the algorithm consists of the following steps: 1.Initialize in(0)←(ǫ,(this,τ1,...,τn−1,⊤,...,⊤))where(τ1,...,τn−1)isthe method’s signature.2.A‘changed’bit is associated to each instruction,all‘changed’bits are set tozero except thefirst.Execute the following loop until no more instructions are marked as‘changed’(i.e.,afix-point is reached).1.Choose a marked instruction i.If there aren’t any,the method is safe(exit).Otherwise,reset the‘changed’bit of the selected instruction.2.Model the effect of the instruction on in(i)by doing the following:–If the instruction uses values from the stack,ensure that:•There are sufficiently many values on the stack,and that•The topmost stack elements are of types that suit the executed in-struction.Otherwise,verification fails.–If the instruction uses local variables:•Ascertain that these local variables are of types that suit the executedinstruction.Otherwise,verification fails.5The LCA operation is frequently called unification.–If the instruction pushes values onto the stack:•Ascertain that there is enough room on the stack for the new values.If the new stack’s height exceeds S max,verification fails;•Add the types produced by the instruction to the top of the stack.–If the instruction modifies local variables,record these new types in out(i).3.Determine the instructions that can potentially follow instruction i.A suc-cessor instruction can be one of the following:–For most instructions,the successor instruction is just the next instruc-tion;–For a goto,the successor instruction is the goto’s jump target;–For an if,both the if’s remote jump target and the next instruction are the successors;–return has no successors.–Verification fails if it is possible to“fall off”the last instruction of the method.4.Unify out(i)with the in(k)-frame of each successor instruction k.–If this successor instruction k is visited for thefirst time,•record that out(i)calculated in step2is now the in(k)-frame of thesuccessor instruction;•mark the successor instruction by setting the‘changed’bit.–If the successor instruction has been visited before,•Unify out(i)with the successor instruction’s(already present)in(k)-frame and update:in(k)←LCA(in(k),out(i)).•If the unification caused modifications in in(k),mark the successorinstruction k by setting its‘changed’bit.5.Go to step1.If the code is safe,the algorithm must exit without reporting a failure.As one can see,the time complexity of this algorithm is upper-bound by the O(D×I×J×L max),where D is the depth of the type lattice,I is the total number of instructions and J is the number of jumps in the method.While from a theoretical standpoint,time complexity can be bounded by a crude upper bound O(I4)6,practical experiments show that each instruction is usually parsed less than twice during the verification process.6In the worst case,all instructions are jumps,and each instruction acts on c different variables,i.e.,L max=c×I,where c is a language-dependent constant representing the maximal number of variables possibly affected by a single instruction.Addition-ally,one may show(stemming from the observation that the definition of a new type requires at least one new instruction)that D is the maximal amongst the depth of the primitive data part of the type lattice L(some langauge-dependent constant) and I.This boils down to a crude upper bound O(I4).Considering that byte-code verification takes place only once upon applet downloading,even a relatively high computational overload would not be a barrier to running a byte-code verifier on board.Space(memory)complexity is much more problematic,since a straightfor-ward coding of Sun’s algorithm yields an implementation where memory com-plexity is bound by O(IL max).Although this is still polynomial in the size of the downloaded applet,one must not forget that if L max RAM cells are avail-able on board for running applets,applets are likely to use up all the available memory so as to optimize their functional features,which in turn would make it impossible to verify these same applets on board.Here again,a straightfor-ward simplification allows to reduce this memory complexity from O(IL max)to O(JL max).3Trading-OffOn-Board RAM Against Communication A smart card is nothing but one element in a distributed computing system which,invariably,comprises terminals(also called card readers)that allow cards to communicate with the outside world.Given that terminals usually possess much more RAM than cards,it seems natural to rely on the terminal’s storage capabilities for running the verification algorithm.The sole challenge being that data stored in the terminal’s RAM can be subject to tampering.Note that the capacity of working with remote objects(Remote Method Invocation)would make the implementation of such a concept rather natural in Java7.3.1The Data Integrity MechanismOur goal being to use of the terminal’s RAM to store the frames created during verification,the card must embark a mechanism allowing to ascertain that frame data is not modified without the card’s consent.Luckily,a classic cryptographic primitive called MAC(Message Authentication Code)[12]does just that.It is important to stress that most modern cards embark ad hoc crypto-graphic co-processors that allow the computation of MACs in a few clock cycles. The on-board operation of such co-processors is particularly easy through the cryptographic classes and Java Card’s standard APIs.Finally,the solution that we are about to describe does not impose upon the terminal any cryptographic computations;and there is no need for the card and the terminal to share secret keys.Before verification starts,the card generates an ephemeral MAC key k;this key will be used only for one method verification.We denote by f k(m)the MAC function,applied to data m.k should be long enough(typically160bits long)to avoid the illicit recycling of data coming from different runs of the verification algorithm.The protocol below describes the solution implemented by our prototype. In the coming paragraphs we use the term working frame,when speaking of 7However,because of the current limitations of Java Cards,the prototype reported in this paper does not rely on RMIs.in(i+1)←out(i)←Φi(in(i)).In other words,the working frame is the current input frame in(i+1)of the instruction i which is just about to be modelled.For simplicity,we assume that instruction number i is located at offset i. Shouldn’t this be the case,a simple lookup table A[i],which output represents the real offset of the i-th instruction,willfix the problem.The card does not keep the frames of the method’s instructions in its own RAM but uses the terminal as a repository for storing them.To ascertain data integrity,the card sends out,along with the data,MACs of the outgoing data. These MACs will subsequently allow the card to ascertain the integrity of the data retrieved from the terminal(in other words,the card simply sends MACs to itself via the terminal).The card associates with each instruction i a counter c i kept in card’s RAM. Each time that instruction i is rechecked(modelled)during thefix-point com-putation,its c i is incremented inside the card.The role of c i is to avoid playback attacks,i.e.the malicious substitution of type information by an older versions of this type information.3.2The New Byte-code Verification StrategyThe initialize step is replaced by repeating the following for2≤i≤I:1.Form a string representing the initialized(void)type information(frame)F ifor instruction i.2.Append to this string a counter c i representing the current number of timesthat instruction i was visited.Start with c i←0.pute r i=f k(unchanged,c i,i,F i)=f k(unchanged,0,i,F i).4.Send to the terminal{unchanged,F i,i,r i}.Complete the initialization step by:1.Sending to the terminal{changed,F1←(ǫ,(this,τ1,...,τn−1,⊤,...,⊤)),1,r1←f k(changed,c1←0,1,F1)},2.Initializing an on-board counterτ←1.In all subsequent descriptions check r i means:re-compute r i based on the current i,the{c i,k}kept in the card and{F i,changed/unchanged bit}sent back by the terminal and if the result disagrees with the r i sent back by the terminal, reject the applet.The mainfix-point loop is the following:1.Ifτ=0accept the applet,else query from the terminal an F i for an instruc-tion i which bit is set to changed.(a)Check if the transition rules allow executing the instruction.In case offailure reject the applet.(b)Apply the transition rules to the type information F i received back fromthe terminal and store the result in the working frame.2.For all potential successors j of the instruction at i:(a)Query the terminal for{F j,r j};check that r j is correct.(b)Unify the working frame with F j.If unification fails reject the applet.(c)If unification yields a frame F′j different than F j then–increment c j,incrementτ–compute r j=f k(changed,c j,j,F′j),and–send to the terminal{changed,F′j,j,r j}.The terminal can now erase the old values at entry j and replace them by the new ones.3.Decrementτ,increment c i,re-compute r i and send{unchanged,F i,i,r i}tothe terminal.Again,the terminal can now erase the old values at entry i and replace them by the new ones.4.Goto1.The algorithm that we have just described only requires the storage of I c i-counters.Since time complexity will never exceed O(I4),any given instruction can never be visited more than O(I4)times.The counter size can hence be bound by O(log I)thereby resulting in an overall on-board space complexity of O(I log I+cL max).where c is a small language-dependent constant(the cL max component of the formula simply represents the memory space necessary for the working frame).Note that although in our presentation we allotted for clarity a c i per in-struction,this is not actually necessary since the same c i can be shared by every sequence of instructions into which no jumps are possible;this O(J log J+cL max) memory complexity optimization is evident to Java verification practitioners.3.3Reducing In-card Memory to O(log I+cL max)By exporting also the c i values to the terminal,we can further reduce card’s memory requirements to O(log I+cL max).This is done by implementing the next protocol in which all the c i values are kept in the terminal.The card generates a second ephemeral MAC key k′and stores a single counter t,initialized to zero.–Initialization:The card computes and sends m i←f k′(i,c i←0,t←0)to the terminal for1≤i≤I.–Read c i:To read a counter c i:•The card sends a query i to the terminal.•The terminal returns{c i,m i}.•The card checks that m i=f k′(i,c i,t)and if this is indeed the case thenc i can be used safely(in case of MAC disagreement the card rejects theapplet).–Increment c i:to increment a counter c i:1.For j=1to I:•Execute Read c j•If i=j,the card instructs the terminal to increment c i.•The card computes m j=f k′(j,c j,t+1)and sends this updated m jto the terminal.2.The card increments t.The value of t being at most equal to the number of steps executed by the program,t occupies an O(log I)space(in practice,a32bit counter).Note,how-ever,that the amount of communication and computations is rather important: for every c i update,the terminal has to send back to the card the values and MACs of all counters associated with the verified method;the card checks all the MACs,updates them correspondingly,and sends them back to the terminal.4Implementation DetailsWe implemented algorithm3.2as a usual Java Card applet.It is uploaded onto the card and after initialization,waits a new applet to be received in order to check it for type safety.Thus,our prototype does not have any access to the Java Card Runtime Environment(JCRE)structures nor to Installer’s functions and by no means can it access information about the current contents of the card and packages residing on it.However,the purpose of our code is to check the type safety of newly uploaded applets.Given that new applets can make use of packages already existing on board,our verifier should have full information about the following structures:–the names of the packages already present on board and classes in these packages;–methods for resident classes,along with their signatures;–fields in resident classes and their types.Since this information cannot be obtained from the card itself,we had to assume that the newly downloaded applet uses only common framework packages,and pre-embed the necessary information about these packages into our verifier.The type lattice information is“derived”by the verifier from the superclass references and interface references stored in the byte arrays of classes.The terminal-side applet plays an active role in the verification process;it calls methods of the card-side applet and sends them all the necessary data.4.1Programming Tools and LibrariesThe prototype has been implemented as a“normal”Java Card applet.It enjoys the full functionality of Sun’s off-card verifier,that we reverse-engineered in the course of this project using a special application called dump,from the JTrek library[13]originally developed by Compaq8.JTrek contains the Trek class library,which allows navigation and manipu-lation of Java classfiles,as well as several applications built around this library; 8JTrek is no longer downloadable from its web page.。